lib/mopti/nelder_mead.rb in mopti-0.1.0 vs lib/mopti/nelder_mead.rb in mopti-0.2.0

- old
+ new

@@ -23,11 +23,11 @@ # # :n_fev=>165, # # :n_iter=>84, # # :fnc=>5.694864987422661e-13} # # *Reference* - # 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. + # 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. class NelderMead include Enumerable # Create a new optimizer with the Nelder-Mead simplex method. # @@ -36,11 +36,11 @@ # @param x_init [Numo::NArray] Initial point. # @param max_iter [Integer] Maximum number of iterations. # If nil is given, max_iter sets to 200 * number of dimensions. # @param xtol [Float] Tolerance for termination for the optimal vector norm. # @param ftol [Float] Tolerance for termination for the objective function value. - def initialize(fnc:, args: nil, x_init:, max_iter: nil, xtol: 1e-6, ftol: 1e-6) + def initialize(fnc:, x_init:, args: nil, max_iter: nil, xtol: 1e-6, ftol: 1e-6) @fnc = fnc @args = args @x_init = x_init @max_iter = max_iter @xtol = xtol @@ -70,17 +70,17 @@ sim = x.class.zeros(n + 1, n) sim[0, true] = x n.times do |k| y = x.dup - y[k] = y[k] != 0 ? (1 + NON_ZERO_TAU) * y[k] : ZERO_TAU + y[k] = (y[k]).zero? ? ZERO_TAU : (1 + NON_ZERO_TAU) * y[k] sim[k + 1, true] = y end fsim = Numo::DFloat.zeros(n + 1) - (n + 1).times { |k| fsim[k] = func(sim[k, true]) } + (n + 1).times { |k| fsim[k] = func(sim[k, true], @args) } n_fev = n + 1 ind = fsim.sort_index fsim = fsim[ind].dup sim = sim[ind, true].dup @@ -89,17 +89,17 @@ while n_iter < max_iter break if ((sim[1..-1, true] - sim[0, true]).abs.flatten.max <= @xtol) && ((fsim[0] - fsim[1..-1]).abs.max <= @ftol) xbar = sim[0...-1, true].sum(0) / n xr = xbar + alpha * (xbar - sim[-1, true]) - fr = func(xr) + fr = func(xr, @args) n_fev += 1 shrink = true if fr < fsim[0] xe = xbar + beta * (xr - xbar) - fe = func(xe) + fe = func(xe, @args) n_fev += 1 shrink = false if fe < fr sim[-1, true] = xe fsim[-1] = fe @@ -111,32 +111,32 @@ shrink = false sim[-1, true] = xr fsim[-1] = fr elsif fr < fsim[-1] xoc = xbar + gamma * (xr - xbar) - foc = func(xoc) + foc = func(xoc, @args) n_fev += 1 if foc <= fr shrink = false sim[-1, true] = xoc fsim[-1] = foc end else xic = xbar - gamma * (xr - xbar) - fic = func(xic) + fic = func(xic, @args) n_fev += 1 if fic < fsim[-1] shrink = false sim[-1, true] = xic fsim[-1] = fic end end if shrink - (1..n).times do |j| + (1..n).to_a.each do |j| sim[j, true] = sim[0, true] + delta * (sim[j, true] - sim[0, true]) - fsim[j] = func(sim[j, true]) + fsim[j] = func(sim[j, true], @args) n_fev += 1 end end ind = fsim.sort_index @@ -154,18 +154,18 @@ private_constant :NON_ZERO_TAU, :ZERO_TAU private - def func(x) - if @args.is_a?(Hash) - @fnc.call(x, **@args) - elsif @args.is_a?(Array) - @fnc.call(x, *@args) - elsif @args.nil? + def func(x, args) + if args.is_a?(Hash) + @fnc.call(x, **args) + elsif args.is_a?(Array) + @fnc.call(x, *args) + elsif args.nil? @fnc.call(x) else - @fnc.call(x, @args) + @fnc.call(x, args) end end end end