2016-02-21 3 views
1

Я хотел использовать масштабирование и закончил тестирование своих документов Paraboloid example from OpenMDAO 0.x с OpenMDAO 1.x, но я получаю странные результаты с или без масштабирования. Вот код:Оптимизация параболоидов, требующая масштабирования

 
from __future__ import print_function 
import sys 

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

class Paraboloid(Component): 

    def __init__(self): 
     super(Paraboloid, self).__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 = params['x'] 
     y = params['y'] 

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

    def linearize(self, params, unknowns, resids): 
     """ Jacobian for our paraboloid.""" 
     x = params['x'] 
     y = params['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 

     return J 

if __name__ == "__main__": 

    top = Problem() 

    root = top.root = Group() 

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

    root.connect('p1.x', 'p.x') 
    root.connect('p2.y', 'p.y') 

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

    top.driver.add_desvar('p1.x', lower=-1000, upper=1000, scaler=0.001) 
    top.driver.add_desvar('p2.y', lower=-1000, upper=1000, scaler=1000.) 
    top.driver.add_objective('p.f_xy') 

    top.setup() 
    top.run() 

    print('\n') 
    print('Minimum of %f found at (%f, %f)' % (top['p.f_xy'], top['p.x'], top['p.y'])) 

, когда я запускаю его на моей системе, это дает:

 
2.7.11 |Anaconda 2.5.0 (64-bit)| (default, Jan 29 2016, 14:26:21) [MSC v.1500 64 bit (AMD64)] 
Python Type "help", "copyright", "credits" or "license" for more information. 
[evaluate paraboloid_optimize_scaled.py] 
############################################## 
Setup: Checking for potential issues... 

No recorders have been specified, so no data will be saved. 

Setup: Check complete. 
############################################## 

Optimization terminated successfully. (Exit mode 0) 
      Current function value: [ 8981902.27846645] 
      Iterations: 1 
      Function evaluations: 12 
      Gradient evaluations: 1 
Optimization Complete 
----------------------------------- 


Minimum of 8981902.278466 found at (3.000000, -4.000000) 

ли я что-то пропустил?

+0

какая версия OpenMDAO 1.x вы работаете? –

+0

На данный момент, я бы сказал, ГОЛОВА. – relf

ответ

1

В зачистные определены противоположно OpenMDAO 1.x, чем они были в 0.x. В 1.x используется следующее отношение масштабирования.

driver_value = (model_value + adder)*scaler 

Поэтому вам нужно было изменить масштабирование по сравнению с тем, что было в старом учебнике. Однако была вторичная проблема, ошибка в ваших аналитических производных, которая также исправлена ​​ниже.

from __future__ import print_function 
import sys 

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

class Paraboloid(Component): 

    def __init__(self): 
     super(Paraboloid, self).__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 = params['x'] 
     y = params['y'] 

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

    def linearize(self, params, unknowns, resids): 
     """ Jacobian for our paraboloid.""" 
     x = params['x'] 
     y = params['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 

     return J 

if __name__ == "__main__": 

    top = Problem() 

    root = top.root = Group() 
    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', 'p.x') 
    root.connect('p2.y', 'p.y') 

    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', lower=-1000, upper=1000,scaler=.001) 
    top.driver.add_objective('p.f_xy') 

    top.setup() 
    top.run() 

    print('\n') 
    print('Minimum of %f found at (%f, %f)' % (top['p.f_xy'], top['p.x'], top['p.y'])) 

Дает:

Optimization terminated successfully. (Exit mode 0) 
      Current function value: [-27.333333] 
      Iterations: 3 
      Function evaluations: 6 
      Gradient evaluations: 3 
Optimization Complete 
----------------------------------- 


Minimum of -27.333333 found at (0.006666, -733.299996) 
+0

Я заметил, что вы установили 'root.fd_options ['force_fd'] = True', действительно, он работает тогда. Вы пытались без форсирования fd? – relf

+0

Хорошо, мой плохой. Мои производные были неправы! Это: 'J ['f_xy', 'x'] = 2000000.0 * x - 6000.0 + 10.0 * y' и' J ['f_xy', 'y'] = 0.0002 * y + 0.08 + 10.0 * x'. После того как я перевернул значения масштабирования, как вы отметили, он работает отлично! – relf

0

Я не могу воспроизвести вашу проблему напрямую. У вас есть некоторые странные масштабирования в методах solve_nonlinear и линеаризации по сравнению с openmdao 0.x tutorial, на которые вы ссылаетесь. Но когда я их очищаю, я получаю правильный ответ, для разумных значений масштабирования и даже для некоторых необоснованных (те, которые вы выбрали, немного экстремальны). Когда вы используете scaler/adder из add_desvar, вам не нужно изменять ваши модели вообще. Эти значения просто изменяют значения, которые оптимизатор видит, чтобы помочь масштабировать, но до того, как их передадут в вашу модель, они должным образом преобразуются обратно в немасштабированные значения.

from __future__ import print_function 
import sys 

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

class Paraboloid(Component): 

    def __init__(self): 
     super(Paraboloid, self).__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 = params['x'] 
     y = params['y'] 

     unknowns['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0 

    def linearize(self, params, unknowns, resids): 
     """ Jacobian for our paraboloid.""" 
     x = params['x'] 
     y = params['y'] 
     J = {} 

     J['f_xy', 'x'] = 2.0*x - 6.0 + y 
     J['f_xy', 'y'] = 2.0*y + 8.0 + x 

     return J 

if __name__ == "__main__": 

    top = Problem() 

    root = top.root = Group() 

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

    root.connect('p1.x', 'p.x') 
    root.connect('p2.y', 'p.y') 

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

    # top.driver.add_desvar('p1.x', lower=-1000, upper=1000) 
    # top.driver.add_desvar('p2.y', lower=-1000, upper=1000) 

    top.driver.add_desvar('p1.x', lower=-1000, upper=1000, scaler=.001) 
    top.driver.add_desvar('p2.y', lower=-1000, upper=1000, scaler=1000.) 
    top.driver.add_objective('p.f_xy') 

    top.setup() 
    top.run() 

    print('\n') 
    print('Minimum of %f found at (%f, %f)' % (top['p.f_xy'], top['p.x'], top['p.y'])) 

дает:

############################################## 
Setup: Checking for potential issues... 

No recorders have been specified, so no data will be saved. 

Setup: Check complete. 
############################################## 

Optimization terminated successfully. (Exit mode 0) 
      Current function value: [-27.33333333] 
      Iterations: 12 
      Function evaluations: 15 
      Gradient evaluations: 12 
Optimization Complete 
----------------------------------- 
+0

На самом деле, я ссылался на [этот пример] (http://openmdao.org/releases/0.13.0/docs/tutorials/optimization/scaler_adder.html) и пытался его реплицировать с помощью OpenMDAO 1.x – relf