2

check_partial_derivatives()以前の質問で示した問題に適用された方法の出力に驚いています:スケーリングを必要とする放物面最適化。そのメソッドへの呼び出しを追加すると:

from __future__ import print_function
システムをインポート

from openmdao.api import IndepVarComp, Component, Problem, Group, ScipyOptimizer

クラス放物面(コンポーネント):

    def __init__(自己):
        super(放物面、自己).__init__()

        self.add_param('x', val=0.0)
        self.add_param('y', val=0.0)

        self.add_output('f_xy', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):

        x = パラメータ['x']
        y = パラメータ['y']

        #unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
        未知数['f_xy'] = (1000.*x-3.)**2 + (1000.*x)*(0.01*y) + (0.01*y+4.)**2 - 3.

    def linearize(self、params、unknowns、resids):
        """ 放物面のヤコビアン"""
        x = パラメータ['x']
        y = パラメータ['y']
        J = {}

        #J['f_xy', 'x'] = 2.0*x - 6.0 + y
        #J['f_xy', 'y'] = 2.0*y + 8.0 + x
        J['f_xy', 'x'] = 2000000.0*x - 6000.0 + 10.0*y
        J['f_xy', 'y'] = 0.0002*y + 0.08 + 10.0*x

        Jを返す

if __name__ == "__main__":

    トップ=問題()

    root = top.root = グループ()
    #root.fd_options['force_fd'] = True

    root.add('p1', IndepVarComp('x', 3.0))
    root.add('p2', IndepVarComp('y', -4.0))
    root.add('p', Paraboloid())

    root.connect('p1.x', 'px')
    root.connect('p2.y', 'py')

    top.driver = ScipyOptimizer()
    top.driver.options['optimizer'] = 'SLSQP'

    top.driver.add_desvar('p1.x', lower=-1000, upper=1000, scaler=1000.)
    top.driver.add_desvar('p2.y', 下限=-1000, 上限=1000, スケーラー=0.001)
    top.driver.add_objective('p.f_xy')


    top.setup()
    top.check_partial_derivatives() # 行を追加
    top.run()


    印刷('\n')
    print('Minimum of %f found at (%f, %f)' % (top['p.f_xy'], top['px'], top['py']))

次の出力が得られます。

部分導関数チェック

----------------
コンポーネント: 'p'
----------------
  p: 'f_xy' wrt 'x'

    前方マグニチュード : 6.000000e+03
    逆マグニチュード : 6.000000e+03
         Fd マグニチュード : 2.199400e+07

    絶対誤差 (Jfor - Jfd) : 2.200000e+07
    絶対誤差 (Jrev - Jfd) : 2.200000e+07
    絶対誤差 (Jfor - Jrev): 0.000000e+00

    相対誤差 (Jfor - Jfd) : 1.000273e+00
    相対誤差 (Jrev - Jfd) : 1.000273e+00
    相対誤差 (Jfor - Jrev): 0.000000e+00

    生の前方微分 (Jfor)

[[-6000.]]

    生逆導関数 (Jrev)

[[-6000.]]

    生の FD デリバティブ (Jfor)

[[ 21994001.]]
 - - - - - - - - - - - - - - - - - - - - - - - - - - -
  p: 'f_xy' wrt 'y'

    前方マグニチュード : 8.000000e-02
    逆マグニチュード : 8.000000e-02
         Fd マグニチュード : 2.200000e+07

    絶対誤差 (Jfor - Jfd) : 2.200000e+07
    絶対誤差 (Jrev - Jfd) : 2.200000e+07
    絶対誤差 (Jfor - Jrev): 0.000000e+00

    相対誤差 (Jfor - Jfd) : 1.000000e+00
    相対誤差 (Jrev - Jfd) : 1.000000e+00
    相対誤差 (Jfor - Jrev): 0.000000e+00

    生の前方微分 (Jfor)

[[ 0.08]]

    生逆導関数 (Jrev)

[[ 0.08]]

    生の FD デリバティブ (Jfor)

[[ 22000000.08]]
最適化が正常に終了しました。(終了モード 0)
            現在の関数値: [-27.33333333]
            反復: 4
            機能評価:6
            勾配評価: 4
最適化完了
-----------------------------------


(0.006667、-733.333333) で見つかった -27.333333 の最小値

最適化は正しい (つまり、導関数が正しいことをほぼ確実に証明している) が、check_partial_derivatives出力は fd と forward/reverse メソッドの間で一貫した結果を示していない。

4

1 に答える 1