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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10f6e681a7b2d60d8915837bc7001a79d9ea796237d9907651481eeb96618213
4
- data.tar.gz: d95ab1a0f2ac0e5d3f040de8309e4c3a9e3b3babe057c02fe553a3702dd3e75c
3
+ metadata.gz: 209395124eb39ffdf43a87f346023646fa5367a66f382378542dabdc15668cdf
4
+ data.tar.gz: 9684de7283ba7ff88d6c8408dead7c8468f11e33b4a8010b1c837a2efeb635aa
5
5
  SHA512:
6
- metadata.gz: 7eae04f38bb591a1a2b13b18c2be747cfccd28551c5ff3cdc5095442f00044d6489407abc1b6db33425cedd5368cff0efc88202b76c5ca27ba3a9a98094ed60d
7
- data.tar.gz: e75187c9e10cd4e9670c5f3c3a795509d35307515dbe98c951eb8059fde47eec4e7dc4190fdf80dbbf45104b2d0a4306caee050a3e0b485b30c8451bfc50ad3f
6
+ metadata.gz: 89cf143fe2b33ab916200814aed666bbcbe2de19852955bcb672ff065939657d2d82dde2e12b14d8cf79aa73d40aebba68d335dd49b68a302af311d7d45f3b3f
7
+ data.tar.gz: bca9b1a012e020669b1b491ff54a40230da72f70efbf8540945239b487d4d6b08fd2a7f3a11600736b40bc6a25f661ed040a0e8077f80273e17a484000a1c045
data/.clang-format ADDED
@@ -0,0 +1,149 @@
1
+ ---
2
+ Language: Cpp
3
+ # BasedOnStyle: LLVM
4
+ AccessModifierOffset: -2
5
+ AlignAfterOpenBracket: Align
6
+ AlignConsecutiveMacros: false
7
+ AlignConsecutiveAssignments: false
8
+ AlignConsecutiveBitFields: false
9
+ AlignConsecutiveDeclarations: false
10
+ AlignEscapedNewlines: Right
11
+ AlignOperands: Align
12
+ AlignTrailingComments: true
13
+ AllowAllArgumentsOnNextLine: true
14
+ AllowAllConstructorInitializersOnNextLine: true
15
+ AllowAllParametersOfDeclarationOnNextLine: true
16
+ AllowShortEnumsOnASingleLine: true
17
+ AllowShortBlocksOnASingleLine: Never
18
+ AllowShortCaseLabelsOnASingleLine: false
19
+ AllowShortFunctionsOnASingleLine: All
20
+ AllowShortLambdasOnASingleLine: All
21
+ AllowShortIfStatementsOnASingleLine: Never
22
+ AllowShortLoopsOnASingleLine: false
23
+ AlwaysBreakAfterDefinitionReturnType: None
24
+ AlwaysBreakAfterReturnType: None
25
+ AlwaysBreakBeforeMultilineStrings: false
26
+ AlwaysBreakTemplateDeclarations: MultiLine
27
+ BinPackArguments: true
28
+ BinPackParameters: true
29
+ BraceWrapping:
30
+ AfterCaseLabel: false
31
+ AfterClass: false
32
+ AfterControlStatement: Never
33
+ AfterEnum: false
34
+ AfterFunction: false
35
+ AfterNamespace: false
36
+ AfterObjCDeclaration: false
37
+ AfterStruct: false
38
+ AfterUnion: false
39
+ AfterExternBlock: false
40
+ BeforeCatch: false
41
+ BeforeElse: false
42
+ BeforeLambdaBody: false
43
+ BeforeWhile: false
44
+ IndentBraces: false
45
+ SplitEmptyFunction: true
46
+ SplitEmptyRecord: true
47
+ SplitEmptyNamespace: true
48
+ BreakBeforeBinaryOperators: None
49
+ BreakBeforeBraces: Attach
50
+ BreakBeforeInheritanceComma: false
51
+ BreakInheritanceList: BeforeColon
52
+ BreakBeforeTernaryOperators: true
53
+ BreakConstructorInitializersBeforeComma: false
54
+ BreakConstructorInitializers: BeforeColon
55
+ BreakAfterJavaFieldAnnotations: false
56
+ BreakStringLiterals: true
57
+ ColumnLimit: 128
58
+ CommentPragmas: '^ IWYU pragma:'
59
+ CompactNamespaces: false
60
+ ConstructorInitializerAllOnOneLineOrOnePerLine: false
61
+ ConstructorInitializerIndentWidth: 4
62
+ ContinuationIndentWidth: 4
63
+ Cpp11BracedListStyle: true
64
+ DeriveLineEnding: true
65
+ DerivePointerAlignment: false
66
+ DisableFormat: false
67
+ ExperimentalAutoDetectBinPacking: false
68
+ FixNamespaceComments: true
69
+ ForEachMacros:
70
+ - foreach
71
+ - Q_FOREACH
72
+ - BOOST_FOREACH
73
+ IncludeBlocks: Preserve
74
+ IncludeCategories:
75
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
76
+ Priority: 2
77
+ SortPriority: 0
78
+ - Regex: '^(<|"(gtest|gmock|isl|json)/)'
79
+ Priority: 3
80
+ SortPriority: 0
81
+ - Regex: '.*'
82
+ Priority: 1
83
+ SortPriority: 0
84
+ IncludeIsMainRegex: '(Test)?$'
85
+ IncludeIsMainSourceRegex: ''
86
+ IndentCaseLabels: false
87
+ IndentCaseBlocks: false
88
+ IndentGotoLabels: true
89
+ IndentPPDirectives: None
90
+ IndentExternBlock: AfterExternBlock
91
+ IndentWidth: 2
92
+ IndentWrappedFunctionNames: false
93
+ InsertTrailingCommas: None
94
+ JavaScriptQuotes: Leave
95
+ JavaScriptWrapImports: true
96
+ KeepEmptyLinesAtTheStartOfBlocks: true
97
+ MacroBlockBegin: ''
98
+ MacroBlockEnd: ''
99
+ MaxEmptyLinesToKeep: 1
100
+ NamespaceIndentation: None
101
+ ObjCBinPackProtocolList: Auto
102
+ ObjCBlockIndentWidth: 2
103
+ ObjCBreakBeforeNestedBlockParam: true
104
+ ObjCSpaceAfterProperty: false
105
+ ObjCSpaceBeforeProtocolList: true
106
+ PenaltyBreakAssignment: 2
107
+ PenaltyBreakBeforeFirstCallParameter: 19
108
+ PenaltyBreakComment: 300
109
+ PenaltyBreakFirstLessLess: 120
110
+ PenaltyBreakString: 1000
111
+ PenaltyBreakTemplateDeclaration: 10
112
+ PenaltyExcessCharacter: 1000000
113
+ PenaltyReturnTypeOnItsOwnLine: 60
114
+ PointerAlignment: Left
115
+ ReflowComments: true
116
+ SortIncludes: true
117
+ SortUsingDeclarations: true
118
+ SpaceAfterCStyleCast: false
119
+ SpaceAfterLogicalNot: false
120
+ SpaceAfterTemplateKeyword: true
121
+ SpaceBeforeAssignmentOperators: true
122
+ SpaceBeforeCpp11BracedList: false
123
+ SpaceBeforeCtorInitializerColon: true
124
+ SpaceBeforeInheritanceColon: true
125
+ SpaceBeforeParens: ControlStatements
126
+ SpaceBeforeRangeBasedForLoopColon: true
127
+ SpaceInEmptyBlock: false
128
+ SpaceInEmptyParentheses: false
129
+ SpacesBeforeTrailingComments: 1
130
+ SpacesInAngles: false
131
+ SpacesInConditionalStatement: false
132
+ SpacesInContainerLiterals: true
133
+ SpacesInCStyleCastParentheses: false
134
+ SpacesInParentheses: false
135
+ SpacesInSquareBrackets: false
136
+ SpaceBeforeSquareBrackets: false
137
+ Standard: Latest
138
+ StatementMacros:
139
+ - Q_UNUSED
140
+ - QT_REQUIRE_VERSION
141
+ TabWidth: 8
142
+ UseCRLF: false
143
+ UseTab: Never
144
+ WhitespaceSensitiveMacros:
145
+ - STRINGIZE
146
+ - PP_STRINGIZE
147
+ - BOOST_PP_STRINGIZE
148
+ ...
149
+
@@ -1,13 +1,13 @@
1
1
  name: build
2
2
 
3
- on: [push]
3
+ on: [push, pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: [ '2.5', '2.6', '2.7' ]
10
+ ruby: [ '2.6', '2.7', '3.0' ]
11
11
  steps:
12
12
  - uses: actions/checkout@v2
13
13
  - name: Set up Ruby ${{ matrix.ruby }}
@@ -16,6 +16,6 @@ jobs:
16
16
  ruby-version: ${{ matrix.ruby }}
17
17
  - name: Build and test with Rake
18
18
  run: |
19
- gem install bundler
19
+ gem install --no-document bundler
20
20
  bundle install --jobs 4 --retry 3
21
21
  bundle exec rake
data/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ ## 0.4.0
2
+ - Add type declaration file: sig/lbfgsb.rbs
3
+
4
+ ## 0.3.2
5
+ - Refactor native extension codes.
6
+ - Update documentations.
7
+
8
+ ## 0.3.1
9
+ - Add GC guard to narray given to native extension method.
10
+
11
+ ## 0.3.0
12
+ - Add library name prefix to functions derived from blas and linpack
13
+ to avoid errors due to collision with the blas functions called by numo-linalg.
14
+
15
+ ## 0.2.0
16
+ - Add an option to minimize method for calculating both function value and gradient vector using fnc.
17
+ If true is given to jcb, fnc is assumed to return the function value and gardient vector as [f, g] array.
18
+
19
+ ## 0.1.0
20
+ - First release.
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in lbfgsb.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
6
+ gem "rake", "~> 13.0"
7
7
  gem "rake-compiler"
8
8
  gem "rspec", "~> 3.0"
9
+ gem "rbs", "~> 1.2"
10
+ gem "steep", "~> 0.44"
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 Atsushi Tatsuma
1
+ Copyright (c) 2020-2021 Atsushi Tatsuma
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  [![Build Status](https://github.com/yoshoku/lbfgsb.rb/workflows/build/badge.svg)](https://github.com/yoshoku/lbfgsb.rb/actions?query=workflow%3Abuild)
4
4
  [![Gem Version](https://badge.fury.io/rb/lbfgsb.svg)](https://badge.fury.io/rb/lbfgsb)
5
- [![BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-orange.svg)](https://github.com/yoshoku/suika/blob/master/LICENSE.txt)
5
+ [![BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-orange.svg)](https://github.com/yoshoku/suika/blob/main/LICENSE.txt)
6
+ [![Documentation](http://img.shields.io/badge/api-reference-blue.svg)](https://yoshoku.github.io/lbfgsb.rb/doc/)
6
7
 
7
8
  Lbfgsb.rb is a Ruby binding for [L-BFGS-B](http://users.iems.northwestern.edu/~nocedal/lbfgsb.html)
8
9
  that is a limited-memory algorithm for solving large nonlinear optimization problems
data/Steepfile ADDED
@@ -0,0 +1,20 @@
1
+ target :lib do
2
+ signature "sig"
3
+ #
4
+ check "lib" # Directory name
5
+ # check "Gemfile" # File name
6
+ # check "app/models/**/*.rb" # Glob
7
+ # # ignore "lib/templates/*.rb"
8
+ #
9
+ # # library "pathname", "set" # Standard libraries
10
+ # library "numo-narray" # Gems
11
+ end
12
+
13
+ # target :spec do
14
+ # signature "sig", "sig-private"
15
+ #
16
+ # check "spec"
17
+ #
18
+ # # library "pathname", "set" # Standard libraries
19
+ # # library "rspec"
20
+ # end
@@ -2,13 +2,8 @@
2
2
 
3
3
  VALUE rb_mLbfgsb;
4
4
 
5
- static
6
- VALUE lbfgsb_min_l_bfgs_b(VALUE self,
7
- VALUE fnc, VALUE x_val, VALUE jcb, VALUE args,
8
- VALUE l_val, VALUE u_val, VALUE nbd_val,
9
- VALUE maxcor, VALUE ftol, VALUE gtol, VALUE maxiter, VALUE disp)
10
- {
11
- long i;
5
+ static VALUE lbfgsb_min_l_bfgs_b(VALUE self, VALUE fnc, VALUE x_val, VALUE jcb, VALUE args, VALUE l_val, VALUE u_val,
6
+ VALUE nbd_val, VALUE maxcor, VALUE ftol, VALUE gtol, VALUE maxiter, VALUE disp) {
12
7
  long n_iter;
13
8
  long n_fev;
14
9
  long n_jev;
@@ -19,12 +14,12 @@ VALUE lbfgsb_min_l_bfgs_b(VALUE self,
19
14
  narray_t* nbd_nary;
20
15
  long n;
21
16
  long m = NUM2LONG(maxcor);
22
- double *x_ptr;
23
- double *l_ptr;
24
- double *u_ptr;
25
- long *nbd_ptr;
17
+ double* x_ptr;
18
+ double* l_ptr;
19
+ double* u_ptr;
20
+ long* nbd_ptr;
26
21
  double f;
27
- double *g;
22
+ double* g;
28
23
  double factr = NUM2DBL(ftol);
29
24
  double pgtol = NUM2DBL(gtol);
30
25
  double* wa;
@@ -35,8 +30,8 @@ VALUE lbfgsb_min_l_bfgs_b(VALUE self,
35
30
  long lsave[4];
36
31
  long isave[44];
37
32
  double dsave[29];
38
- double* g_ptr;
39
33
  VALUE g_val;
34
+ VALUE fg_arr;
40
35
  VALUE ret;
41
36
 
42
37
  GetNArray(x_val, x_nary);
@@ -108,29 +103,34 @@ VALUE lbfgsb_min_l_bfgs_b(VALUE self,
108
103
  wa = ALLOC_N(double, (2 * m + 5) * n + 12 * m * m + 12 * m);
109
104
  iwa = ALLOC_N(long, 3 * n);
110
105
 
106
+ g_val = Qnil;
111
107
  f = 0.0;
112
- for (i = 0; i < n; g[i++] = 0.0);
108
+ memset(g, 0, n * sizeof(*g));
113
109
  strcpy(task, "START");
114
110
  n_fev = 0;
115
111
  n_jev = 0;
116
112
 
117
113
  for (n_iter = 0; n_iter < max_iter;) {
118
- setulb_(
119
- &n, &m, x_ptr, l_ptr, u_ptr, nbd_ptr, &f, g, &factr, &pgtol, wa, iwa,
120
- task, &iprint, csave, lsave, isave, dsave
121
- );
114
+ setulb_(&n, &m, x_ptr, l_ptr, u_ptr, nbd_ptr, &f, g, &factr, &pgtol, wa, iwa, task, &iprint, csave, lsave, isave, dsave);
122
115
  if (strncmp(task, "FG", 2) == 0) {
123
- f = NUM2DBL(rb_funcall(self, rb_intern("fnc"), 3, fnc, x_val, args));
124
- g_val = rb_funcall(self, rb_intern("jcb"), 3, jcb, x_val, args);
125
- n_fev += 1;
126
- n_jev += 1;
127
- if (CLASS_OF(g_val) != numo_cDFloat) g_val = rb_funcall(numo_cDFloat, rb_intern("cast"), 1, g_val);
128
- if (!RTEST(nary_check_contiguous(g_val))) g_val = nary_dup(g_val);
129
- g_ptr = (double*)na_get_pointer_for_read(g_val);
130
- for (i = 0; i < n; i++) g[i] = g_ptr[i];
116
+ if (RB_TYPE_P(jcb, T_TRUE)) {
117
+ fg_arr = rb_funcall(self, rb_intern("fnc"), 3, fnc, x_val, args);
118
+ f = NUM2DBL(rb_ary_entry(fg_arr, 0));
119
+ g_val = rb_ary_entry(fg_arr, 1);
120
+ } else {
121
+ f = NUM2DBL(rb_funcall(self, rb_intern("fnc"), 3, fnc, x_val, args));
122
+ g_val = rb_funcall(self, rb_intern("jcb"), 3, jcb, x_val, args);
123
+ }
124
+ n_fev++;
125
+ n_jev++;
126
+ if (CLASS_OF(g_val) != numo_cDFloat)
127
+ g_val = rb_funcall(numo_cDFloat, rb_intern("cast"), 1, g_val);
128
+ if (!RTEST(nary_check_contiguous(g_val)))
129
+ g_val = nary_dup(g_val);
130
+ memcpy(g, na_get_pointer_for_read(g_val), n * sizeof(*g));
131
+ RB_GC_GUARD(g_val);
131
132
  } else if (strncmp(task, "NEW_X", 5) == 0) {
132
- n_iter += 1;
133
- continue;
133
+ n_iter++;
134
134
  } else {
135
135
  break;
136
136
  }
@@ -150,12 +150,15 @@ VALUE lbfgsb_min_l_bfgs_b(VALUE self,
150
150
  rb_hash_aset(ret, ID2SYM(rb_intern("n_jev")), LONG2NUM(n_jev));
151
151
  rb_hash_aset(ret, ID2SYM(rb_intern("success")), strncmp(task, "CONV", 4) == 0 ? Qtrue : Qfalse);
152
152
 
153
+ RB_GC_GUARD(x_val);
154
+ RB_GC_GUARD(l_val);
155
+ RB_GC_GUARD(u_val);
156
+ RB_GC_GUARD(nbd_val);
157
+
153
158
  return ret;
154
159
  }
155
160
 
156
- void
157
- Init_lbfgsbext(void)
158
- {
161
+ void Init_lbfgsbext(void) {
159
162
  rb_mLbfgsb = rb_define_module("Lbfgsb");
160
163
  /* The value of double epsilon used in the native extension. */
161
164
  rb_define_const(rb_mLbfgsb, "DBL_EPSILON", DBL2NUM(DBL_EPSILON));
@@ -2,8 +2,10 @@
2
2
  #define LBFGSB_RB_H 1
3
3
 
4
4
  #include <float.h>
5
+ #include <string.h>
5
6
 
6
7
  #include <ruby.h>
8
+
7
9
  #include <numo/narray.h>
8
10
  #include <numo/template.h>
9
11
 
@@ -5,38 +5,7 @@
5
5
  */
6
6
  #include "blas.h"
7
7
 
8
- double dnrm2_(long *n, double *x, long *incx)
9
- {
10
- long i__1, i__2;
11
- double ret_val, d__1, d__2, d__3;
12
- static long i__;
13
- static double scale;
14
-
15
- --x;
16
-
17
- ret_val = 0.;
18
- scale = 0.;
19
- i__1 = *n;
20
- i__2 = *incx;
21
- for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
22
- d__2 = scale, d__3 = (d__1 = x[i__], fabs(d__1));
23
- scale = d__2 >= d__3 ? d__2 : d__3;
24
- }
25
- if (scale == 0.) {
26
- return ret_val;
27
- }
28
- i__2 = *n;
29
- i__1 = *incx;
30
- for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) {
31
- d__1 = x[i__] / scale;
32
- ret_val += d__1 * d__1;
33
- }
34
- ret_val = scale * sqrt(ret_val);
35
- return ret_val;
36
- }
37
-
38
- int daxpy_(long *n, double *da, double *dx, long *incx, double *dy, long *incy)
39
- {
8
+ int lbfgsb_rb_daxpy_(long* n, double* da, double* dx, long* incx, double* dy, long* incy) {
40
9
  long i__1;
41
10
  static long i__, m, ix, iy, mp1;
42
11
 
@@ -100,8 +69,7 @@ L40:
100
69
  return 0;
101
70
  }
102
71
 
103
- int dcopy_(long *n, double *dx, long *incx, double *dy, long *incy)
104
- {
72
+ int lbfgsb_rb_dcopy_(long* n, double* dx, long* incx, double* dy, long* incy) {
105
73
  long i__1;
106
74
  static long i__, m, ix, iy, mp1;
107
75
 
@@ -165,8 +133,7 @@ L40:
165
133
  return 0;
166
134
  }
167
135
 
168
- double ddot_(long *n, double *dx, long *incx, double *dy, long *incy)
169
- {
136
+ double lbfgsb_rb_ddot_(long* n, double* dx, long* incx, double* dy, long* incy) {
170
137
  long i__1;
171
138
  double ret_val;
172
139
  static long i__, m, ix, iy, mp1;
@@ -224,16 +191,15 @@ L40:
224
191
  mp1 = m + 1;
225
192
  i__1 = *n;
226
193
  for (i__ = mp1; i__ <= i__1; i__ += 5) {
227
- dtemp = dtemp + dx[i__] * dy[i__] + dx[i__ + 1] * dy[i__ + 1]
228
- + dx[i__ + 2] * dy[i__ + 2] + dx[i__ + 3] * dy[i__ + 3] + dx[i__ + 4] * dy[i__ + 4];
194
+ dtemp = dtemp + dx[i__] * dy[i__] + dx[i__ + 1] * dy[i__ + 1] + dx[i__ + 2] * dy[i__ + 2] + dx[i__ + 3] * dy[i__ + 3] +
195
+ dx[i__ + 4] * dy[i__ + 4];
229
196
  }
230
197
  L60:
231
198
  ret_val = dtemp;
232
199
  return ret_val;
233
200
  }
234
201
 
235
- int dscal_(long *n, double *da, double *dx, long *incx)
236
- {
202
+ int lbfgsb_rb_dscal_(long* n, double* da, double* dx, long* incx) {
237
203
  long i__1, i__2;
238
204
  static long i__, m, mp1, nincx;
239
205