def run_iteration(self):
        """ Note: cobyla controls the looping."""

        try:
            self.iact, self.error_code, self.nfvals = \
              cobyla(self._func, self.nparam, self.ncon, self.x,
                   self.rhobeg, self.rhoend, self.iprint, self.maxfun,
                   self.work_vector, self.iact, self.error_code, self.nfvals,
                   self.iout, self.output_filename, self.ff, self.gg)

        except Exception as err:
            self._logger.error(str(err))
            raise

        if self.iprint > 0:
            closeunit(self.iout)

        # Log any errors
        if self.error_code != 0:
            self._logger.warning(self.error_messages[self.error_code])

        # Iteration is complete
        self._continue = False
    def run_iteration(self):
        """ Note: cobyla controls the looping."""

        try:
            self.iact, self.error_code, self.nfvals = \
              cobyla(self._func, self.nparam, self.ncon, self.x,
                   self.rhobeg, self.rhoend, self.iprint, self.maxfun,
                   self.work_vector, self.iact, self.error_code, self.nfvals,
                   self.iout, self.output_filename, self.ff, self.gg)

        except Exception as err:
            self._logger.error(str(err))
            raise

        if self.iprint > 0:
            closeunit(self.iout)

        # Log any errors
        if self.error_code != 0:
            self._logger.warning(self.error_messages[self.error_code])

        # Iteration is complete
        self._continue = False
class COBYLAdriver(Driver):
    """Minimize a function using the Constrained Optimization BY Linear
    Approximation (COBYLA) method.

    COBYLA is gradient-free and can handle inequality constraints.
    
    Note: Constraints should be added using the OpenMDAO convention
    (positive = violated).
    """
    
    implements(IHasParameters, IHasIneqConstraints, IHasObjective, IOptimizer)
    
    # pylint: disable-msg=E1101
    rhobeg = Float(1.0, iotype='in', 
                   desc = 'Reasonable initial changes to the variables.')

    rhoend = Float(1e-4, iotype='in', 
                   desc = 'Final accuracy in the optimization (not precisely guaranteed).')

    iprint = Enum(1, [0, 1, 2, 3], iotype='in',
                  desc = 'Controls the frequency of output: 0 (no output),1,2,3.')
    
    maxfun = Int(1000, iotype='in',
                  desc = 'Maximum number of function evaluations.')
    
    iout = Int(6, iotype='in',
                  desc = 'Fortran output unit. Leave this at 6 for STDOUT.')
    
    output_filename = Str('cobyla.out', iotype='in',
                          desc = 'Name of output file (if iout not 6).')
    
    error_code = Int(0, iotype='out',
                  desc = 'Error code returned from COBYLA.')
    

    def __init__(self):
        
        super(COBYLAdriver, self).__init__()
        
        self.error_messages = {
            1 : 'Max. number of function evaluations reached',
            2 : 'Rounding errors are becoming damaging'
        }
        
        self.x = zeros(0,'d')
        self.work_vector = zeros(0,'d')
        self.gg = zeros(0,'d')
        self.iact = zeros(0,'d')
        
        self.ff = 0
        self.nfvals = 0
        
    def start_iteration(self):
        """Perform initial setup before iteration loop begins."""

        self.nparam = len(self.get_parameters().values())
        self.ncon = len(self.get_ineq_constraints())
        self.ncon += 2*self.nparam
        self.x = zeros(self.nparam,'d')
        self.g = zeros(self.ncon,'d')
        self.work_vector = zeros(self.ncon,'d')
        
        # get the initial values of the parameters
        params = self.get_parameters().values()
        for i, val in enumerate(params):
            self.x[i] = val.evaluate(self.parent)
            
        n = self.nparam
        m = self.ncon
        self.work_vector = zeros([n*(3*n+2*m+11)+4*m+6],'d')
        self.iact = zeros([m+1],'i')
        self.gg = zeros([m],'d')
            
        self._continue = True
        
    def run_iteration(self):
        """ Note: cobyla controls the looping."""
        
        try:
            self.iact, self.error_code, self.nfvals = \
              cobyla(self._func, self.nparam, self.ncon, self.x, \
                   self.rhobeg, self.rhoend, self.iprint, self.maxfun, \
                   self.work_vector, self.iact, self.error_code, self.nfvals, \
                   self.iout, self.output_filename, self.ff, self.gg)
            
        except Exception, err:
            self._logger.error(str(err))
            raise       
        
        if self.iprint > 0 :
            closeunit(self.iout)

        # Log any errors
        if self.error_code != 0 :
            self._logger.warning(self.error_messages[self.error_code])
        
        # Iteration is complete
        self._continue = False