nAG数値計算ライブラリ
> 最適化アルゴリズムExample集
> 導関数を用いない非線形最小二乗問題の解法
非線形最小二乗問題(導関数無し最適化-DFO)
このExampleでは、nAG最適化モデリングスイートにおけるオプションのアルゴリズムパラメータの取り扱い方法を示すために、非線形最小二乗問題を導関数無し最適化(DFO)で解いています。具体的には、KowalikとOsborne関数を最小化するタスクに取り組んでいます。
目的関数:
| タスク | 式 |
|---|---|
| minimize | \(\sum_{i=1}^{11} \left(z_i - x_0 \frac{y_i (y_i + x_1)}{y_i (y_i + x_2) + x_3}\right)^2\) |
ここで、\(y_i\) と \(z_i\) は以下の通りです。
\[ \begin{aligned} y = [&4.0, 2.0, 1.0, 0.5, 0.25, \\ &0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625] \end{aligned} \]
\[ \begin{aligned} z = [&0.1957, 0.1947, 0.1735, 0.1600, 0.0844, \\ &0.0627, 0.0456, 0.0342, 0.0323, 0.0235, 0.0246] \end{aligned} \]
決定変数:
| 変数 | 範囲 |
|---|---|
| \(x_0\) | \((-\infty, \infty)\) |
| \(x_1\) | \([0.2, 1.0]\) |
| \(x_2\) | \((-\infty, \infty)\) |
| \(x_3\) | \([0.3, \infty)\) |
制約条件:
| 制約 | 式 |
|---|---|
| 変数\(x_1\)の下限 | \(x_1 \geq 0.2\) |
| 変数\(x_1\)の上限 | \(x_1 \leq 1.0\) |
| 変数\(x_3\)の下限 | \(x_3 \geq 0.3\) |
変数\(x_0\)と\(x_2\)には明示的な制約条件はありませんが、実装上は\(\pm 10^{20}\)の範囲に限定されています。
Exampleの実行コマンド:
python -m naginterfaces.library.examples.opt.handle_solve_dfls_ex
ソースコード表示コマンド:
python -c "import inspect; from naginterfaces.library.examples.opt import handle_solve_dfls_ex; print(''.join(inspect.getsourcelines(handle_solve_dfls_ex)[0]))"
出力結果例:
naginterfaces.library.opt.handle_solve_dfls Python Example Results.
Minimizing the Kowalik and Osborne function.
Status: Converged, small trust region size
Value of the objective 4.02423E-04
Number of objective function evaluations 27
Number of steps 10
マニュアル:
ソース:
#!/usr/bin/env python3
"""naginterfaces.library.opt.handle_solve_dfls Python Example."""
# nAG Copyright 2018-2020.
# pylint: disable=invalid-name
from naginterfaces.base import utils
from naginterfaces.library import opt
def main():
"""
Example for :func:`naginterfaces.library.opt.handle_solve_dfls`.
Derivative-free solver for a nonlinear least squares objective function.
Demonstrates handling optional algorithmic parameters in the nAG
optimization modelling suite.
>>> main()
naginterfaces.library.opt.handle_solve_dfls Python Example Results.
Minimizing the Kowalik and Osborne function.
...
Status: Converged, small trust region size
...
Value of the objective 4.02423E-04
Number of objective function evaluations 27
Number of steps 10
...
"""
print(
'naginterfaces.library.opt.handle_solve_dfls Python Example Results.'
)
print('Minimizing the Kowalik and Osborne function.')
# The initial guess:
x = [0.25, 0.39, 0.415, 0.39]
# The Kowalik and Osborne function:
y = [
4., 2., 1., 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625
]
z = [
0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627, 0.0456, 0.0342,
0.0323, 0.0235, 0.0246
]
objfun = lambda x, _nres, inform: (
z - x[0]*(y*(y+x[1]))/(y*(y+x[2]) + x[3]), inform,
)
# Create a handle for the problem:
handle = opt.handle_init(nvar=len(x))
# Define the residuals structure:
nres = 11
opt.handle_set_nlnls(
handle, nres,
)
# Define the bounds:
opt.handle_set_simplebounds(
handle,
bl=[-1.e20, 0.2, -1.e20, 0.3],
bu=[1.e20, 1., 1.e20, 1.e20],
)
# Set some algorithmic options.
# Relax the main convergence criteria slightly:
opt.handle_opt_set(handle, 'DFO Trust Region Tolerance = 5.0e-6')
# Turn off option printing:
opt.handle_opt_set(handle, 'Print Options = NO')
# Print the solution:
opt.handle_opt_set(handle, 'Print Solution = YES')
# Use an explicit I/O manager for abbreviated iteration output:
iom = utils.FileObjManager(locus_in_output=False)
# Solve the problem:
opt.handle_solve_dfls(handle, objfun, x, nres, io_manager=iom)
# Destroy the handle:
opt.handle_free(handle)
if __name__ == '__main__':
import doctest
import sys
sys.exit(
doctest.testmod(
None, verbose=True, report=False,
optionflags=doctest.ELLIPSIS | doctest.REPORT_NDIFF,
).failed
)