I am currently trying to do some optimization for locations on a map using OpenMDAO 1.7.2. The (preexisting) modules that do the calculations only support integer coordinates (resolution of one meter).
For now I am optimizing using an IndepVarComp for each direction each containing a float vector. These values are then rounded before using them, but this is quite inefficient because the solver mainly tries variations smaller below one.
When I attempt to initialize an IndepVarComp with an integer vector the first iteration works fine (uses inital values), but in the second iteration fails, because the data in IndepVarComp is set to an empty ndarray.
Looking through the OpenMDAO source code I found out that this is because
indep_var_comp._init_unknowns_dict['x']['size'] == 0
which happens in Component's _add_variable() method whenever the data type is not differentiable.
Here is an example problem which illustrates how defining an integer IndepVarComp fails:
from openmdao.api import Component, Group, IndepVarComp, Problem, ScipyOptimizer
INITIAL_X = 1
class ResultCalculator(Component):
def __init__(self):
super(ResultCalculator, self).__init__()
self.add_param('x', INITIAL_X)
self.add_output('y', 0.)
def solve_nonlinear(self, params, unknowns, resids):
unknowns['y'] = (params['x'] - 3) ** 2 - 4
problem = Problem()
problem.root = Group()
problem.root.add('indep_var_comp', IndepVarComp('x', INITIAL_X))
problem.root.add('calculator', ResultCalculator())
problem.root.connect('indep_var_comp.x', 'calculator.x')
problem.driver = ScipyOptimizer()
problem.driver.options['optimizer'] = 'COBYLA'
problem.driver.add_desvar('indep_var_comp.x')
problem.driver.add_objective('calculator.y')
problem.setup()
problem.run()
Which fails with
ValueError: setting an array element with a sequence.
Note that everythings works out fine if I set INITIAL_X = 0..
How am I supposed to optimize for integers?