Dakota を使ってみる

2015年10月31日

はじめに

Dakota を使ってみる。

バージョン

Dakota 6.2 Windows 版

Dakota とは

Dakota (Design Analysis Kit for Optimization and Terascale Applications) は米国のサンディア国立研究所で開発された、エンジニアリング上の問題を解くための最適化ツールである。

Dakota のインストール

ここ からダウンロードする。バイナリパッケージを適当なところに置いて、パスを通す。

動作テスト

適当に作業ディレクトリを作る。インストールディレクトリの "examples/users" の中にある "rosen_multidim.in" を作業ディレクトリにコピー。 "rosen_multidim.in" を開いて、下記のように "graphics" の行をコメントにする (少なくとも今回用いた Windows 版バイナリではグラフィクスは使えない)。

environment
  #graphics
  tabular_graphics_data
    tabular_graphics_file = 'rosen_multidim.dat'

次のようにコマンドを実行。

>dakota -i rosen_multidim.in

メッセージが流れれば OK。

問題を解いてみる

問題

ここでは 2 の平方根を関数の最小化により求める。次のような関数を定義する。

f(x) = x*x - 2

この関数の絶対値が最小になる x を求める。

Dakota は外部プログラムを呼び出してそれに対して最適化を行うことができる。ここでは上記関数を定義したプログラムを Python で書く。

Dakota インプットファイル

Dakota のインプットファイルをつぎのようにする。

sqrt2.in

# Dakota Input File: sqrt2.in
# Usage:
#   dakota -i sqrt2.in
environment

method
  conmin_frcg
    max_iterations = 100
    convergence_tolerance = 1e-6

model
  single

variables
  continuous_design = 1
    initial_point     1.0
    lower_bounds      0.0
    upper_bounds      2.0
    descriptors       'x'

interface
  system
    analysis_driver = 'sqrt2.py'
    parameters_file = 'params.in'
    results_file = 'results.out'

responses
  objective_functions = 1
  numerical_gradients
    method_source dakota
    interval_type forward
    fd_gradient_step_size = 1e-6
  no_hessians

"method" と書かれた部分が最適化手法の指定を行うところだが、ここでは最小化を行うために "conmin_frcg" を指定している。

"variables" で初期値と最小値・最大値を指定して x を定義している。

"interface" 部分がプログラムの呼び出し指定である。"analysis_driver" で呼び出すプログラムを指定。"parameters_file" でプログラムが読み込む (Dakota が書き出す) 入力ファイルを指定、"results_file" でプログラムが書き出す (Dakota が読み込む) 結果ファイルを指定している。

"responses" では "conmin_frcg" 用に勾配の設定 ("numerical_gradients") をしている。

呼び出すプログラム "sqrt2.py" は以下のとおりである。

sqrt2.py

def sqrt2(x):
    return x*x - 2.


f = open('params.in', 'r')

l = f.readline()
l = f.readline()
x = float(l.split()[0])

f.close()


f = open('results.out', 'w')

f.write('%.15e' % abs(sqrt2(x)))

f.close()

'params.in' は、以下のような内容になっている。

                                          1 variables
                     1.000000000000000e+000 x
                                          1 functions
                                          1 ASV_1:obj_fn
                                          1 derivative_variables
                                          1 DVV_1:x
                                          0 analysis_components
                                          2 eval_id

今回は x の値を読むだけなので、1 行目を飛ばして 2 行目だけ読み込んでいる。

'results.out' は、今回はとりあえず関数の絶対値を書き込んでおけばよい。

Dakota を実行。

>dakota -i sqrt2.in

以下の結果が得られた。

<<<<< Best parameters          =
                     1.4142132936e+000 x