mopti 0.1.0 → 0.2.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: a94c3e3b4ecd74032308bd83bd3b018f23469b90cee573456638888c88649c72
4
- data.tar.gz: bd9c811610325eba50c2ba7659fa514ad6c84c3dd6b1ee7559999a08d6928812
3
+ metadata.gz: c9e81da580fe5dd2be2958e34bee75fe5c82bb29240edf43bb7d01c89522f863
4
+ data.tar.gz: 43648573d898ae4fdbce70ce84b6f6dbcfd5109ea95eb743e9fb51fc2101251b
5
5
  SHA512:
6
- metadata.gz: 759379528285a342e0228fa6199a1f4babf217e173b8f836b701e3faa5203af8783bf4f97e6d873a1af38d7d915f98e94c1021618d39503f505b341bb46f87b0
7
- data.tar.gz: 6f2f010305f6b217da688f7ab0b4ed7328b06e97fbc8ccd792ec9f0360448883584652474cb55d59f63ce36d6e4668a39359c58c33dcba194589d09509888352
6
+ metadata.gz: 2de393870f138bfeba855c7d1c95d8263e85a30e0e9fb4a3a65ae6614784531865b32cafc0761ab856331dc66b9f19df4a00c8bfff3ff69eb07a9b850902c718
7
+ data.tar.gz: a71eead28cac1eb28e4b3154fabd846d11468ae803f5e7cbe5e4cb04faed18d1a468793131e465b282504b71bde2ae03db114fa245f08a8b9d0be99b3f3cbfcf
@@ -1,24 +1,21 @@
1
- name: Ruby
1
+ name: build
2
2
 
3
- on: [push]
3
+ on: [push, pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
7
-
8
7
  runs-on: ubuntu-latest
9
-
10
8
  strategy:
11
9
  matrix:
12
- ruby: ['2.4.x', '2.5.x', '2.6.x', '2.7.x']
13
-
10
+ ruby: [ '2.6', '2.7', '3.0' ]
14
11
  steps:
15
- - uses: actions/checkout@v2
16
- - name: Set up Ruby
17
- uses: actions/setup-ruby@v1
18
- with:
19
- ruby-version: ${{ matrix.ruby }}
20
- - name: Build and test with Rake
21
- run: |
22
- gem install bundler
23
- bundle install --jobs 4 --retry 3
24
- bundle exec rake
12
+ - uses: actions/checkout@v2
13
+ - name: Set up Ruby
14
+ uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.ruby }}
17
+ - name: Build and test with Rake
18
+ run: |
19
+ gem install bundler
20
+ bundle install --jobs 4 --retry 3
21
+ bundle exec rake
data/.rubocop.yml CHANGED
@@ -2,6 +2,9 @@ require:
2
2
  - rubocop-performance
3
3
  - rubocop-rspec
4
4
 
5
+ AllCops:
6
+ NewCops: enable
7
+
5
8
  Layout/LineLength:
6
9
  Max: 145
7
10
  IgnoredPatterns: ['(\A|\s)#']
data/CHANGELOG.md CHANGED
@@ -1,2 +1,7 @@
1
+ # 0.2.0
2
+ - Add type declaration files.
3
+ - Refactor some codes with type check.
4
+ - Fix some configuration files.
5
+
1
6
  # 0.1.0
2
7
  - First release.
data/Gemfile CHANGED
@@ -5,3 +5,5 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem "rbs", "~> 1.2"
9
+ 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,7 @@
2
2
 
3
3
  ![Ruby](https://github.com/yoshoku/mopti/workflows/Ruby/badge.svg)
4
4
  [![Gem Version](https://badge.fury.io/rb/mopti.svg)](https://badge.fury.io/rb/mopti)
5
- [![BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-orange.svg)](https://github.com/yoshoku/mopti/blob/master/LICENSE.txt)
5
+ [![BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-orange.svg)](https://github.com/yoshoku/mopti/blob/main/LICENSE.txt)
6
6
  [![Documentation](http://img.shields.io/badge/api-reference-blue.svg)](https://yoshoku.github.io/mopti/doc/)
7
7
 
8
8
  Mopti is a multivariate optimization library in Ruby.
@@ -89,9 +89,9 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
89
89
 
90
90
  ## Contributing
91
91
 
92
- Bug reports and pull requests are welcome on GitHub at https://github.com/yoshoku/mopti. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/yoshoku/mopti/blob/master/CODE_OF_CONDUCT.md).
92
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yoshoku/mopti. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/yoshoku/mopti/blob/main/CODE_OF_CONDUCT.md).
93
93
 
94
94
 
95
95
  ## Code of Conduct
96
96
 
97
- Everyone interacting in the Mopti project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/yoshoku/mopti/blob/master/CODE_OF_CONDUCT.md).
97
+ Everyone interacting in the Mopti project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/yoshoku/mopti/blob/main/CODE_OF_CONDUCT.md).
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
@@ -25,7 +25,7 @@ module Mopti
25
25
  # # :fnc=>5.694864987422661e-13}
26
26
  #
27
27
  # *Reference*
28
- # 1. F. Gao and L. Han, "Implementing the Nelder-Mead simplex algorithm with adaptive parameters," Computational Optimization and Applications, vol. 51 (1), pp. 259--277, 2012.
28
+ # 1. Gao, F. and Han, L., "Implementing the Nelder-Mead simplex algorithm with adaptive parameters," Computational Optimization and Applications, vol. 51 (1), pp. 259--277, 2012.
29
29
  class NelderMead
30
30
  include Enumerable
31
31
 
@@ -38,7 +38,7 @@ module Mopti
38
38
  # If nil is given, max_iter sets to 200 * number of dimensions.
39
39
  # @param xtol [Float] Tolerance for termination for the optimal vector norm.
40
40
  # @param ftol [Float] Tolerance for termination for the objective function value.
41
- def initialize(fnc:, args: nil, x_init:, max_iter: nil, xtol: 1e-6, ftol: 1e-6)
41
+ def initialize(fnc:, x_init:, args: nil, max_iter: nil, xtol: 1e-6, ftol: 1e-6)
42
42
  @fnc = fnc
43
43
  @args = args
44
44
  @x_init = x_init
@@ -72,13 +72,13 @@ module Mopti
72
72
  sim[0, true] = x
73
73
  n.times do |k|
74
74
  y = x.dup
75
- y[k] = y[k] != 0 ? (1 + NON_ZERO_TAU) * y[k] : ZERO_TAU
75
+ y[k] = (y[k]).zero? ? ZERO_TAU : (1 + NON_ZERO_TAU) * y[k]
76
76
  sim[k + 1, true] = y
77
77
  end
78
78
 
79
79
  fsim = Numo::DFloat.zeros(n + 1)
80
80
 
81
- (n + 1).times { |k| fsim[k] = func(sim[k, true]) }
81
+ (n + 1).times { |k| fsim[k] = func(sim[k, true], @args) }
82
82
  n_fev = n + 1
83
83
 
84
84
  ind = fsim.sort_index
@@ -91,13 +91,13 @@ module Mopti
91
91
 
92
92
  xbar = sim[0...-1, true].sum(0) / n
93
93
  xr = xbar + alpha * (xbar - sim[-1, true])
94
- fr = func(xr)
94
+ fr = func(xr, @args)
95
95
  n_fev += 1
96
96
 
97
97
  shrink = true
98
98
  if fr < fsim[0]
99
99
  xe = xbar + beta * (xr - xbar)
100
- fe = func(xe)
100
+ fe = func(xe, @args)
101
101
  n_fev += 1
102
102
  shrink = false
103
103
  if fe < fr
@@ -113,7 +113,7 @@ module Mopti
113
113
  fsim[-1] = fr
114
114
  elsif fr < fsim[-1]
115
115
  xoc = xbar + gamma * (xr - xbar)
116
- foc = func(xoc)
116
+ foc = func(xoc, @args)
117
117
  n_fev += 1
118
118
  if foc <= fr
119
119
  shrink = false
@@ -122,7 +122,7 @@ module Mopti
122
122
  end
123
123
  else
124
124
  xic = xbar - gamma * (xr - xbar)
125
- fic = func(xic)
125
+ fic = func(xic, @args)
126
126
  n_fev += 1
127
127
  if fic < fsim[-1]
128
128
  shrink = false
@@ -132,9 +132,9 @@ module Mopti
132
132
  end
133
133
 
134
134
  if shrink
135
- (1..n).times do |j|
135
+ (1..n).to_a.each do |j|
136
136
  sim[j, true] = sim[0, true] + delta * (sim[j, true] - sim[0, true])
137
- fsim[j] = func(sim[j, true])
137
+ fsim[j] = func(sim[j, true], @args)
138
138
  n_fev += 1
139
139
  end
140
140
  end
@@ -156,15 +156,15 @@ module Mopti
156
156
 
157
157
  private
158
158
 
159
- def func(x)
160
- if @args.is_a?(Hash)
161
- @fnc.call(x, **@args)
162
- elsif @args.is_a?(Array)
163
- @fnc.call(x, *@args)
164
- elsif @args.nil?
159
+ def func(x, args)
160
+ if args.is_a?(Hash)
161
+ @fnc.call(x, **args)
162
+ elsif args.is_a?(Array)
163
+ @fnc.call(x, *args)
164
+ elsif args.nil?
165
165
  @fnc.call(x)
166
166
  else
167
- @fnc.call(x, @args)
167
+ @fnc.call(x, args)
168
168
  end
169
169
  end
170
170
  end
@@ -42,7 +42,7 @@ module Mopti
42
42
  # # :jcb=>1.8698188678645777e-07}
43
43
  #
44
44
  # *Reference*
45
- # 1. M F. Moller, "A Scaled Conjugate Gradient Algorithm for Fast Supervised Learning," Neural Networks, Vol. 6, pp. 525--533, 1993.
45
+ # 1. Moller, M F., "A Scaled Conjugate Gradient Algorithm for Fast Supervised Learning," Neural Networks, Vol. 6, pp. 525--533, 1993.
46
46
  class ScaledConjugateGradient
47
47
  include Enumerable
48
48
 
@@ -56,7 +56,7 @@ module Mopti
56
56
  # @param xtol [Float] Tolerance for termination for the optimal vector norm.
57
57
  # @param ftol [Float] Tolerance for termination for the objective function value.
58
58
  # @param jtol [Float] Tolerance for termination for the gradient norm.
59
- def initialize(fnc:, jcb:, args: nil, x_init:, max_iter: 200, xtol: 1e-6, ftol: 1e-8, jtol: 1e-7)
59
+ def initialize(fnc:, jcb:, x_init:, args: nil, max_iter: 200, xtol: 1e-6, ftol: 1e-8, jtol: 1e-7)
60
60
  @fnc = fnc
61
61
  @jcb = jcb
62
62
  @x_init = x_init
@@ -82,10 +82,10 @@ module Mopti
82
82
  return to_enum(__method__) unless block_given?
83
83
 
84
84
  x = @x_init
85
- f_prev = func(x)
85
+ f_prev = func(x, @args)
86
86
  n_fev = 1
87
87
  f_curr = f_prev
88
- j_next = jacb(x)
88
+ j_next = jacb(x, @args)
89
89
  n_jev = 1
90
90
 
91
91
  j_curr = j_next.dot(j_next)
@@ -109,7 +109,7 @@ module Mopti
109
109
 
110
110
  sigma = SIGMA_INIT / Math.sqrt(kappa)
111
111
  x_plus = x + sigma * d
112
- j_plus = jacb(x_plus)
112
+ j_plus = jacb(x_plus, @args)
113
113
  n_jev += 1
114
114
  theta = d.dot(j_plus - j_next) / sigma
115
115
  end
@@ -117,12 +117,15 @@ module Mopti
117
117
  delta = theta + beta * kappa
118
118
  if delta <= 0
119
119
  delta = beta * kappa
120
- beta -= theta / kappa
120
+ # TODO: Investigate the cause of the type error.
121
+ # Cannot assign a value of type `::Complex` to a variable of type `::Float`
122
+ # beta -= theta / kappa
123
+ beta = (beta - (theta / kappa)).to_f
121
124
  end
122
125
  alpha = -mu / delta
123
126
 
124
127
  x_next = x + alpha * d
125
- f_next = func(x_next)
128
+ f_next = func(x_next, @args)
126
129
  n_fev += 1
127
130
 
128
131
  delta = 2 * (f_next - f_prev) / (alpha * mu)
@@ -146,15 +149,15 @@ module Mopti
146
149
  f_prev = f_next
147
150
 
148
151
  j_prev = j_next
149
- j_next = jacb(x)
152
+ j_next = jacb(x, @args)
150
153
  n_jev += 1
151
154
 
152
155
  j_curr = j_next.dot(j_next)
153
156
  break if j_curr <= @jtol
154
157
  end
155
158
 
156
- beta = [beta * 4, BETA_MAX].min if delta < 0.25
157
- beta = [beta / 4, BETA_MIN].max if delta > 0.75
159
+ beta = beta * 4 < BETA_MAX ? beta * 4 : BETA_MAX if delta < 0.25
160
+ beta = beta / 4 > BETA_MIN ? beta / 4 : BETA_MIN if delta > 0.75
158
161
 
159
162
  if n_successes == x.size
160
163
  d = -j_next
@@ -175,27 +178,27 @@ module Mopti
175
178
 
176
179
  private
177
180
 
178
- def func(x)
179
- if @args.is_a?(Hash)
180
- @fnc.call(x, **@args)
181
- elsif @args.is_a?(Array)
182
- @fnc.call(x, *@args)
183
- elsif @args.nil?
181
+ def func(x, args)
182
+ if args.is_a?(Hash)
183
+ @fnc.call(x, **args)
184
+ elsif args.is_a?(Array)
185
+ @fnc.call(x, *args)
186
+ elsif args.nil?
184
187
  @fnc.call(x)
185
188
  else
186
- @fnc.call(x, @args)
189
+ @fnc.call(x, args)
187
190
  end
188
191
  end
189
192
 
190
- def jacb(x)
191
- if @args.is_a?(Hash)
192
- @jcb.call(x, **@args)
193
- elsif @args.is_a?(Array)
194
- @jcb.call(x, *@args)
195
- elsif @args.nil?
193
+ def jacb(x, args)
194
+ if args.is_a?(Hash)
195
+ @jcb.call(x, **args)
196
+ elsif args.is_a?(Array)
197
+ @jcb.call(x, *args)
198
+ elsif args.nil?
196
199
  @jcb.call(x)
197
200
  else
198
- @jcb.call(x, @args)
201
+ @jcb.call(x, args)
199
202
  end
200
203
  end
201
204
  end
data/lib/mopti/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mopti
4
4
  # The version of Mopti you are using.
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
data/sig/mopti.rbs ADDED
@@ -0,0 +1,5 @@
1
+ module Mopti
2
+ VERSION: String
3
+
4
+ def self?.minimize: (algorithm: String algorithm, **untyped args) -> Hash[Symbol, untyped]?
5
+ end
@@ -0,0 +1,21 @@
1
+ module Mopti
2
+ class NelderMead
3
+ include Enumerable[untyped]
4
+
5
+ @fnc: Method | Proc
6
+
7
+ def initialize: (fnc: Method | Proc fnc,
8
+ x_init: Numo::DFloat x_init, ?args: untyped? args, ?max_iter: Integer? max_iter,
9
+ ?xtol: Float xtol, ?ftol: Float ftol) -> void
10
+
11
+ # def each: () { (x: Numo::DFloat, n_fev: Integer, n_iter: Integer, fnc: Float) -> untyped } -> untyped
12
+ def each: () { (untyped) -> untyped } -> untyped
13
+
14
+ private
15
+
16
+ NON_ZERO_TAU: Float
17
+ ZERO_TAU: Float
18
+
19
+ def func: (Numo::DFloat x, untyped args) -> Float
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Mopti
2
+ class ScaledConjugateGradient
3
+ include Enumerable[untyped]
4
+
5
+ @fnc: Method | Proc
6
+ @jcb: Method | Proc
7
+
8
+ def initialize: (fnc: Method | Proc fnc, jcb: Method | Proc jcb,
9
+ x_init: Numo::DFloat x_init, ?args: untyped? args, ?max_iter: Integer max_iter,
10
+ ?xtol: Float xtol, ?ftol: Float ftol, ?jtol: Float jtol) -> void
11
+
12
+ # def each: () { (x: Numo::DFloat, n_fev: Integer, n_jev: Integer, n_iter: Integer, fnc: Float, jcb: Numo::DFloat) -> untyped } -> untyped
13
+ def each: () { (untyped) -> untyped } -> untyped
14
+
15
+ private
16
+
17
+ SIGMA_INIT: Float
18
+ BETA_MIN: Float
19
+ BETA_MAX: Float
20
+
21
+ def func: (Numo::DFloat x, untyped args) -> Float
22
+ def jacb: (Numo::DFloat x, untyped args) -> Numo::DFloat
23
+ end
24
+ end
data/sig/patch.rbs ADDED
@@ -0,0 +1,20 @@
1
+ module Numo
2
+ class NArray
3
+ def self.zeros: (*untyped) -> untyped
4
+ def dot: (untyped b) -> untyped
5
+ def empty?: () -> bool
6
+ def ndim: () -> Integer
7
+ def shape: () -> Array[Integer]
8
+ def swapaxes: (Integer, Integer) -> untyped
9
+ end
10
+
11
+ class DFloat < NArray
12
+ def -@: () -> untyped
13
+ def +: (untyped) -> untyped
14
+ def -: (untyped) -> untyped
15
+ def *: (untyped) -> untyped
16
+ def /: (untyped) -> untyped
17
+ def []: (*untyped) -> untyped
18
+ def []=: (*untyped) -> untyped
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mopti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-19 00:00:00.000000000 Z
11
+ date: 2021-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -43,11 +43,16 @@ files:
43
43
  - LICENSE.txt
44
44
  - README.md
45
45
  - Rakefile
46
+ - Steepfile
46
47
  - lib/mopti.rb
47
48
  - lib/mopti/nelder_mead.rb
48
49
  - lib/mopti/scaled_conjugate_gradient.rb
49
50
  - lib/mopti/version.rb
50
51
  - mopti.gemspec
52
+ - sig/mopti.rbs
53
+ - sig/mopti/nelder_mead.rbs
54
+ - sig/mopti/scaled_conjugate_gradient.rbs
55
+ - sig/patch.rbs
51
56
  homepage: https://github.com/yoshoku/mopti
52
57
  licenses:
53
58
  - BSD-3-Clause
@@ -71,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
76
  - !ruby/object:Gem::Version
72
77
  version: '0'
73
78
  requirements: []
74
- rubygems_version: 3.1.2
79
+ rubygems_version: 3.1.6
75
80
  signing_key:
76
81
  specification_version: 4
77
82
  summary: Multivariate Optimization Library in Ruby.