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

        n = self.nparam
        m = self.ncon
        meq = self.neqcon

        la = max(m, 1)
        gg = zeros([la], 'd')
        df = zeros([n+1], 'd')
        dg = zeros([la, n+1], 'd')

        mineq = m - meq + 2*(n+1)
        lsq = (n+1)*((n+1)+1) + meq*((n+1)+1) + mineq*((n+1)+1)
        lsi = ((n+1)-meq+1)*(mineq+2) + 2*mineq
        lsei = ((n+1)+mineq)*((n+1)-meq) + 2*meq + (n+1)
        slsqpb = (n+1)*(n/2) + 2*m + 3*n + 3*(n+1) + 1
        lw = lsq + lsi + lsei + slsqpb + n + m
        w = zeros([lw], 'd')
        ljw = max(mineq, (n+1)-meq)
        jw = zeros([ljw], 'i')

        try:
            dg, self.error_code, self.nfunc, self.ngrad = \
              slsqp(self.ncon, self.neqcon, la, self.nparam,
                    self.x, self.x_lower_bounds, self.x_upper_bounds,
                    self.ff, gg, df, dg, self.accuracy, self.maxiter,
                    self.iprint-1, self.iout, self.output_filename,
                    self.error_code, w, lw, jw, ljw,
                    self.nfunc, self.ngrad,
                    self._func, self._grad)

            #slsqp(m,meq,la,n,xx,xl,xu,ff,gg,df,dg,acc,maxit,iprint,
            #      iout,ifile,mode,w,lw,jw,ljw,nfunc,ngrad,slfunc,slgrad)

        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])
            self.exit_flag = 0
        else: 
            self.exit_flag = 1


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

        n = self.nparam
        m = self.ncon
        meq = self.neqcon

        la = max(m, 1)
        gg = zeros([la], 'd')
        df = zeros([n + 1], 'd')
        dg = zeros([la, n + 1], 'd')

        mineq = m - meq + 2 * (n + 1)
        lsq = (n + 1) * ((n + 1) + 1) + meq * ((n + 1) + 1) + mineq * (
            (n + 1) + 1)
        lsi = ((n + 1) - meq + 1) * (mineq + 2) + 2 * mineq
        lsei = ((n + 1) + mineq) * ((n + 1) - meq) + 2 * meq + (n + 1)
        slsqpb = (n + 1) * (n / 2) + 2 * m + 3 * n + 3 * (n + 1) + 1
        lw = lsq + lsi + lsei + slsqpb + n + m
        w = zeros([lw], 'd')
        ljw = max(mineq, (n + 1) - meq)
        jw = zeros([ljw], 'i')

        try:
            dg, self.error_code, self.nfunc, self.ngrad = \
              slsqp(self.ncon, self.neqcon, la, self.nparam,
                    self.x, self.x_lower_bounds, self.x_upper_bounds,
                    self.ff, gg, df, dg, self.accuracy, self.maxiter,
                    self.iprint-1, self.iout, self.output_filename,
                    self.error_code, w, lw, jw, ljw,
                    self.nfunc, self.ngrad,
                    self._func, self._grad)

            #slsqp(m,meq,la,n,xx,xl,xu,ff,gg,df,dg,acc,maxit,iprint,
            #      iout,ifile,mode,w,lw,jw,ljw,nfunc,ngrad,slfunc,slgrad)

        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])
            self.exit_flag = 0
        else:
            self.exit_flag = 1

        # Iteration is complete
        self._continue = False
Exemple #3
0
class SLSQPdriver(DriverUsesDerivatives):
    """Minimize a function using the Sequential Least SQuares Programming
    (SLSQP) method.

    SLSQP is a gradient optimizer that can handle both equality and
    inequality constraints.
    
    Note: Constraints should be added using the OpenMDAO convention
    (positive = violated).
    """
    
    implements(IHasParameters, IHasConstraints, IHasObjective)
    
    # pylint: disable-msg=E1101
    accuracy = Float(1.0e-6, iotype='in', 
                     desc = 'Convergence accuracy')

    maxiter = Int(50, iotype='in', 
                   desc = 'Maximum number of iterations.')

    iprint = Enum(0, [0, 1, 2, 3], iotype='in',
                  desc = 'Controls the frequency of output: 0 (no output),1,2,3.')
    
    iout = Int(6, iotype='in',
                  desc = 'Fortran output unit. Leave  this at 6 for STDOUT.')
    
    output_filename = Str('slsqp.out', iotype='in',
                          desc = 'Name of output file (if iout not 6).')
    
    error_code = Int(0, iotype='out',
                  desc = 'Error code returned from SLSQP.')
    
    
    def __init__(self, *args, **kwargs):
        
        super(SLSQPdriver, self).__init__(*args, **kwargs)
        
        self.error_messages = {
            -1 : "Gradient evaluation required (g & a)",
             1 : "Function evaluation required (f & c)",
             2 : "More equality constraints than independent variables",
             3 : "More than 3*n iterations in LSQ subproblem",
             4 : "Inequality constraints incompatible",
             5 : "Singular matrix E in LSQ subproblem",
             6 : "Singular matrix C in LSQ subproblem",
             7 : "Rank-deficient equality constraint subproblem HFTI",
             8 : "Positive directional derivative for linesearch",
             9 : "Iteration limit exceeded",        
        }
        
        self.x = zeros(0,'d')
        self.x_lower_bounds = zeros(0,'d')
        self.x_upper_bounds = zeros(0,'d')
        
        # We auto-fill the slot because the gradient is required
        # in this implementation
        self.differentiator = FiniteDifference()
        
    def start_iteration(self):
        """Perform initial setup before iteration loop begins."""
        
        if not self.differentiator:
            msg = 'A differentiator must be socketed for this driver.'
            self.raise_exception(msg, RuntimeError)

        self.nparam = len(self.get_parameters().values())
        self.ncon = len(self.get_constraints())
        self.neqcon = len(self.get_eq_constraints())
        
        # get the initial values of the parameters
        self.x = zeros(self.nparam,'d')
        params = self.get_parameters().values()
        for i, val in enumerate(params):
            self.x[i] = val.evaluate(self.parent)
            
        # create lower and upper bounds arrays
        self.x_lower_bounds = zeros(self.nparam)
        self.x_upper_bounds = zeros(self.nparam)
        for i, param in enumerate(params):
            self.x_lower_bounds[i] = param.low
            self.x_upper_bounds[i] = param.high        
            
        self.ff = 0
        self.nfunc = 0
        self.ngrad = 0

        self._continue = True
        
    def run_iteration(self):
        """ Note: slsqp controls the looping."""
        
        n = self.nparam
        m = self.ncon
        meq = self.neqcon
        
        la = max(m,1)
        self.gg = zeros([la], 'd')
        df = zeros([n+1], 'd')
        dg = zeros([la, n+1], 'd')
        
        mineq = m - meq + 2*(n+1)
        lsq = (n+1)*((n+1)+1) + meq*((n+1)+1) + mineq*((n+1)+1)
        lsi = ((n+1)-meq+1)*(mineq+2) + 2*mineq
        lsei = ((n+1)+mineq)*((n+1)-meq) + 2*meq + (n+1)
        slsqpb = (n+1)*(n/2) + 2*m + 3*n + 3*(n+1) + 1
        lw = lsq + lsi + lsei + slsqpb + n + m
        w = zeros([lw], 'd')
        ljw = max(mineq,(n+1)-meq)
        jw = zeros([ljw], 'i')
        
        try:
            dg, self.error_code, self.nfunc, self.ngrad = \
              slsqp(self.ncon, self.neqcon, la, self.nparam, \
                    self.x, self.x_lower_bounds, self.x_upper_bounds, \
                    self.ff, self.gg, df, dg, self.accuracy, self.maxiter, \
                    self.iprint-1, self.iout, self.output_filename, \
                    self.error_code, w, lw, jw, ljw, \
                    self.nfunc, self.ngrad, \
                    self._func, self._grad)
                    
            #slsqp(m,meq,la,n,xx,xl,xu,ff,gg,df,dg,acc,maxit,iprint,
            #      iout,ifile,mode,w,lw,jw,ljw,nfunc,ngrad,slfunc,slgrad)            
            
        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