コード例 #1
0
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  store_hst=False,
                  hot_start=False,
                  disp_opts=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
        Run Optimizer (Optimize Routine)

        **Keyword arguments:**

        - opt_problem -> INST: Optimization instance
        - sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
        - store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
        - disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
        - store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
        - hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
        - sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
        - sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

        Additional arguments and keyword arguments are passed to the objective function call.

        Documentation last updated:  February. 2, 2011 - Ruben E. Perez
        '''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyPSQP - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        # end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print 'pyPSQP: Parallel objective Function Analysis requires mpi4py'
            # end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            # end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        # end

        myrank = self.myrank

        #
        def_fname = self.options['IFILE'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        # ======================================================================
        # PSQP - Objective/Constraint Values Storage
        # ======================================================================
        def eval(x):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    # end
                # end
                xn = xg
            else:
                xn = x
            # end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function (Real Valued)
            fail = 0
            f = []
            g = []
            if (myrank == 0):
                if self.h_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        [f, g, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    # end
                    # end
            # end

            if self.pll:
                self.h_start = Bcast(self.h_start, root=0)
            # end
            if self.h_start and self.pll:
                [f, g, fail] = Bcast([f, g, fail], root=0)
            elif not self.h_start:
                [f, g, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            # end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(f, 'obj')
                    log_file.write(g, 'con')
                    log_file.write(fail, 'fail')
                # end
            # end

            # Objective Assigment
            if isinstance(f, float):
                f = [f]
            # end
            for i in xrange(len(opt_problem._objectives.keys())):
                if isinstance(f[i], complex):
                    ff[i] = f[i].astype(float)
                else:
                    ff[i] = f[i]
                # end
            # end

            # Constraints Assigment
            i = 0
            for j in xrange(len(opt_problem._constraints.keys())):
                if isinstance(g[j], complex):
                    gg[i] = g[j].astype(float)
                else:
                    gg[i] = g[j]
                # end
                i += 1
            # end

            # Gradients
            if self.h_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    # end
                # end
                if self.pll:
                    self.h_start = Bcast(self.h_start, root=0)
                # end
                if self.h_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                # end
            # end

            if not self.h_start:
                #
                dff, dgg = gradient.getGrad(x, group_ids, f, g, *args,
                                            **kwargs)

            # end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            # end

            # Store
            self.stored_data['x'] = copy.copy(x)
            self.stored_data['f'] = copy.copy(ff)
            self.stored_data['g'] = copy.copy(gg)
            self.stored_data['df'] = copy.copy(dff)
            self.stored_data['dg'] = copy.copy(dgg)

            return

        # ======================================================================
        # PSQP - Objective Values Function
        # ======================================================================
        def pobj(n, x, f):

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            # end

            ff = self.stored_data['f']

            return ff[0]

        # ======================================================================
        # PSQP - Constraint Values Function
        # ======================================================================
        def pcon(n, k, x, g):

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            # end

            gg = self.stored_data['g']

            return gg[k - 1]

        # ======================================================================
        # PSQP - Objective Gradients Function
        # ======================================================================
        def pdobj(n, x, df):

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            # end

            df = self.stored_data['df']

            return df[0]

        # ======================================================================
        # PSQP - Constraint Gradients Function
        # ======================================================================
        def pdcon(n, k, x, dg):

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            # end

            dg = self.stored_data['dg']

            return dg[k - 1]

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xi = []
        xx = []
        for key in opt_problem._variables.keys():
            xl.append(opt_problem._variables[key].lower)
            xu.append(opt_problem._variables[key].upper)
            xi.append(3)
            xx.append(opt_problem._variables[key].value)
        # end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xi = numpy.array(xi)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            # end
        # end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        if ncon > 0:
            gi = []
            gg = []
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    gi.append(5)
                elif opt_problem._constraints[key].type == 'i':
                    gi.append(2)
                # end
                gg.append(opt_problem._constraints[key].value)
            # end
            gg.append(0.0)
            gl = numpy.zeros([ncon], numpy.float)
            gu = numpy.zeros([ncon], numpy.float)
            gi = numpy.array(gi, numpy.float)
            gg = numpy.array(gg, numpy.float)
        else:
            gl = numpy.array([0], numpy.float)
            gu = numpy.array([0], numpy.float)
            gi = numpy.array([0], numpy.float)
            gg = numpy.array([0], numpy.float)
        # end

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        # end
        ff = numpy.array(ff, numpy.float)

        # Setup argument list values
        nf = numpy.array([nvar], numpy.int)
        nc = numpy.array([ncon], numpy.int)
        mit = numpy.array([self.options['MIT'][1]], numpy.int)
        mfv = numpy.array([self.options['MFV'][1]], numpy.int)
        met = numpy.array([self.options['MET'][1]], numpy.int)
        mec = numpy.array([self.options['MEC'][1]], numpy.int)
        xmax = numpy.array([self.options['XMAX'][1]], numpy.float)
        tolx = numpy.array([self.options['TOLX'][1]], numpy.float)
        tolc = numpy.array([self.options['TOLC'][1]], numpy.float)
        tolg = numpy.array([self.options['TOLG'][1]], numpy.float)
        rpf = numpy.array([self.options['RPF'][1]], numpy.float)
        gmax = numpy.array([0], numpy.float)
        cmax = numpy.array([0], numpy.float)
        if (myrank == 0):
            if (self.options['IPRINT'][1] <= 2):
                iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
            else:
                raise IOError('Incorrect Output Level Setting')
            # end
        else:
            iprint = numpy.array([0], numpy.int)
        # end
        iout = numpy.array([self.options['IOUT'][1]], numpy.int)
        ifile = self.options['IFILE'][1]
        if (myrank == 0):
            if (iprint != 0):
                if os.path.isfile(ifile):
                    os.remove(ifile)
                # end
                # end
        # end
        iterm = numpy.array([0], numpy.int)

        # Storage Arrays
        self.stored_data = {}
        self.stored_data['x'] = {}  # numpy.zeros([nvar],float)
        self.stored_data['f'] = {}  # numpy.zeros([nobj],float)
        self.stored_data['g'] = {}  # numpy.zeros([ncon],float)
        self.stored_data['df'] = {}  # numpy.zeros([nvar],float)
        self.stored_data['dg'] = {}  # numpy.zeros([ncon,nvar],float)

        # Run PSQP
        t0 = time.time()
        psqp.psqp_wrap(nf, nc, xx, xi, xl, xu, gg, gi, gl, gu, mit, mfv, met,
                       mec, xmax, tolx, tolc, tolg, rpf, ff, gmax, cmax,
                       iprint, iout, ifile, iterm, pobj, pdobj, pcon, pdcon)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                # end
                # end
        # end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = iterm[0]
        sol_inform['text'] = self.getInform(iterm[0])

        if store_sol:

            sol_name = 'PSQP Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if sol_options.has_key('defaults'):
                del sol_options['defaults']
            # end

            sol_evals = psqp.stat.nfv + psqp.stat.nfg * nvar

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            # end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            # end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = gg[i]
                    i += 1
                # end
            else:
                sol_cons = {}
            # end

            sol_lambda = {}

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        # end

        return ff, xx, sol_inform
コード例 #2
0
ファイル: pyKSOPT.py プロジェクト: swryan/pyOpt
	def __solve__(self, opt_problem={}, sens_type='FD', store_sol=True, store_hst=False, hot_start=False, disp_opts=False, sens_mode='', sens_step={}, *args, **kwargs):
		
		'''
		Run Optimizer (Optimize Routine)
		
		**Keyword arguments:**
		
		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD' 
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True 
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]
		
		Additional arguments and keyword arguments are passed to the objective function call.
		
		Documentation last updated:  February. 2, 2011 - Ruben E. Perez
		'''
		
		# 
		if ((self.poa) and (sens_mode.lower() == 'pgc')):
			raise NotImplementedError("pyKSOPT - Current implementation only allows single level parallelization, either 'POA' or 'pgc'")
		#end
		
		if self.poa or (sens_mode.lower() == 'pgc'):
			try:
				import mpi4py
				from mpi4py import MPI
			except ImportError:
				print 'pyKSOPT: Parallel objective Function Analysis requires mpi4py'
			#end
			comm = MPI.COMM_WORLD
			nproc = comm.Get_size()
			if (mpi4py.__version__[0] == '0'):
				Bcast = comm.Bcast
			elif (mpi4py.__version__[0] == '1'):
				Bcast = comm.bcast
			#end
			self.pll = True
			self.myrank = comm.Get_rank()
		else:
			self.pll = False
			self.myrank = 0
		#end
		
		myrank = self.myrank
		
		# 
		def_fname = self.options['IFILE'][1].split('.')[0]
		hos_file, log_file, tmp_file = self._setHistory(opt_problem.name, store_hst, hot_start, def_fname)
		
		# 
		gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step, *args, **kwargs)
		
		
		#======================================================================
		# KSOPT - Objective/Constraint Values Function
		#======================================================================
		def ksobj(nv,no,nc,x,f,g):
			
			# Variables Groups Handling
			if opt_problem.use_groups:
				xg = {}
				for group in group_ids.keys():
					if (group_ids[group][1]-group_ids[group][0] == 1):
						xg[group] = x[group_ids[group][0]]
					else:
						xg[group] = x[group_ids[group][0]:group_ids[group][1]]
					#end
				#end
				xn = xg
			else:
				xn = x
			#end
			
			# Flush Output Files
			self.flushFiles()
			
			# Evaluate User Function
			fail = 0
			ff = []
			gg = []
			if (myrank == 0):
				if self.h_start:
					[vals,hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
					if hist_end:
						self.h_start = False
						hos_file.close()
					else:
						[ff,gg,fail] = [vals['obj'][0][0],vals['con'][0],int(vals['fail'][0][0])]
					#end
				#end
			#end
			
			if self.pll:
				self.h_start = Bcast(self.h_start,root=0)
			#end
			if self.h_start and self.pll:
				[ff,gg,fail] = Bcast([ff,gg,fail],root=0)
			elif not self.h_start:	
				[ff,gg,fail] = opt_problem.obj_fun(xn, *args, **kwargs)
			#end
			
			# Store History
			if (myrank == 0):
				if self.sto_hst:
					log_file.write(x,'x')
					log_file.write(ff,'obj')
					log_file.write(gg,'con')
					log_file.write(fail,'fail')
				#end
			#end
			
			# Objective Assigment
			if isinstance(ff,float):
				ff = [ff]
			#end
			for i in xrange(len(opt_problem._objectives.keys())):
				if isinstance(ff[i],complex):
					f[i] = ff[i].astype(float)
				else:
					f[i] = ff[i]
				#end
			#end
			
			# Constraints Assigment
			for i in xrange(len(opt_problem._constraints.keys())):
				if isinstance(gg[i],complex):
					g[i] = gg[i].astype(float)
				else:
					g[i] = gg[i]
				#end
			#end
			
			return f,g
		
		
		#======================================================================
		# KSOPT - Objective/Constraint Gradients Function
		#======================================================================
		def ksgrd(nv,no,nc,x,f,g,df,dg):
			
			if self.h_start:
				dff = []
				dgg = []
				if (myrank == 0):
					[vals,hist_end] = hos_file.read(ident=['grad_obj','grad_con'])
					if hist_end:
						self.h_start = False
						hos_file.close()
					else:
						dff = vals['grad_obj'][0].reshape((len(opt_problem._objectives.keys()),len(opt_problem._variables.keys())))
						dgg = vals['grad_con'][0].reshape((len(opt_problem._constraints.keys()),len(opt_problem._variables.keys())))	
					#end
				#end
				if self.pll:
					self.h_start = Bcast(self.h_start,root=0)
				#end
				if self.h_start and self.pll:
					[dff,dgg] = Bcast([dff,dgg],root=0)
				#end
			#end
			
			if not self.h_start:	
				
				# 
				dff,dgg = gradient.getGrad(x, group_ids, f, g, *args, **kwargs)
				
			#end
			
			# Store History
			if self.sto_hst and (myrank == 0):
				log_file.write(dff,'grad_obj')
				log_file.write(dgg,'grad_con')
			#end
			
			# Gradient Assignment
			for i in xrange(len(opt_problem._variables.keys())):
				for j in xrange(len(opt_problem._objectives.keys())):
					df[j,i] = dff[j,i]
				#end
				for j in xrange(len(opt_problem._constraints.keys())):
					dg[j,i] = dgg[j,i]
				#end
			#end
			
			return df,dg
		
		
		
		# Variables Handling
		nvar = len(opt_problem._variables.keys())
		xl = []
		xu = []
		xx = []
		for key in opt_problem._variables.keys():
			if (opt_problem._variables[key].type == 'c'):
				xl.append(opt_problem._variables[key].lower)
				xu.append(opt_problem._variables[key].upper)
				xx.append(opt_problem._variables[key].value)
			elif (opt_problem._variables[key].type == 'i'):
				raise IOError('KSOPT cannot handle integer design variables')
			elif (opt_problem._variables[key].type == 'd'):
				raise IOError('KSOPT cannot handle discrete design variables')
			#end
		#end
		xl = numpy.array(xl)
		xu = numpy.array(xu)
		xx = numpy.array(xx)
		
		# Variables Groups Handling
		group_ids = {}
		if opt_problem.use_groups:
			k = 0
			for key in opt_problem._vargroups.keys():
				group_len = len(opt_problem._vargroups[key]['ids'])
				group_ids[opt_problem._vargroups[key]['name']] = [k,k+group_len]
				k += group_len
			#end
		#end
		
		# Constraints Handling
		ncon = len(opt_problem._constraints.keys())
		gg = []
		if ncon > 0:
			for key in opt_problem._constraints.keys():
				if opt_problem._constraints[key].type == 'e':
					raise IOError('KSOPT cannot handle equality constraints')
				#end
				gg.append(opt_problem._constraints[key].value)
			#end
		#end
		gg = numpy.array(gg)
		
		# Objective Handling
		objfunc = opt_problem.obj_fun
		nobj = len(opt_problem._objectives.keys())
		ff = []
		for key in opt_problem._objectives.keys():
			ff.append(opt_problem._objectives[key].value)
		#end
		ff = numpy.array(ff)
		
		
		# Setup argument list values
		ndv = numpy.array([nvar], numpy.int)
		nob = numpy.array([nobj], numpy.int)
		ncn = numpy.array([ncon], numpy.int)
		nwork0 = 63
		nwork1 = 3*nobj + ncon + 12*nvar + nvar*(nvar+1)
		nwork2 = nobj*nvar + ncon*nvar
		nwork3 = 2*max(2*nvar,nobj+ncon)
		nworkS = nwork0 + nwork1 + nwork2 + nwork3
		nwork = numpy.array([nworkS], numpy.int)
		work = numpy.zeros([nwork], numpy.float)
		itmax = numpy.array([self.options['ITMAX'][1]], numpy.int)
		rdfun = numpy.array([self.options['RDFUN'][1]], numpy.float)
		rhomin = numpy.array([self.options['RHOMIN'][1]], numpy.float)
		rhomax = numpy.array([self.options['RHOMAX'][1]], numpy.float)
		iout = numpy.array([self.options['IOUT'][1]], numpy.int)
		if (myrank == 0):
			if (self.options['IPRINT'][1]>=0 and self.options['IPRINT'][1]<=3):
				iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
			else:
				raise IOError('Incorrect Output Level Setting')
			#end
		else:
			iprint = numpy.array([0], numpy.int)
		#end
		ifile = self.options['IFILE'][1]
		if (iprint > 0):
			if os.path.isfile(ifile):
				os.remove(ifile)
			#end
		#end
		
		nfun = numpy.array([0], numpy.int)
		ngrd = numpy.array([0], numpy.int)
		
		
		# Run KSOPT
		t0 = time.time()
		ksopt.ksmain(ndv,nob,ncn,xx,xl,xu,ff,gg,work,nwork,
			itmax,rdfun,rhomin,rhomax,iout,iprint,ifile,
			nfun,ngrd,ksobj,ksgrd)
		sol_time = time.time() - t0
		
		if (myrank == 0):
			if self.sto_hst:
				log_file.close()
				if tmp_file:
					hos_file.close()
					name = hos_file.filename
					os.remove(name+'.cue')
					os.remove(name+'.bin')
					os.rename(name+'_tmp.cue',name+'.cue')
					os.rename(name+'_tmp.bin',name+'.bin')
				#end
			#end		
		#end
		
		if (iprint > 0):
			ksopt.closeunit(self.options['IOUT'][1])
		#end		
		
		
		# Store Results
		sol_inform = {}
		sol_inform['value'] = []
		sol_inform['text'] = {}
		
		if store_sol:
			
			sol_name = 'KSOPT Solution to ' + opt_problem.name
			
			sol_options = copy.copy(self.options)
			if sol_options.has_key('defaults'):
				del sol_options['defaults']
			#end
			
			sol_evals = nfun[0] + ngrd[0]*nvar
			
			sol_vars = copy.deepcopy(opt_problem._variables)
			i = 0
			for key in sol_vars.keys():
				sol_vars[key].value = xx[i]
				i += 1
			#end
			
			sol_objs = copy.deepcopy(opt_problem._objectives)
			i = 0
			for key in sol_objs.keys():
				sol_objs[key].value = ff[i]
				i += 1
			#end
			
			if ncon > 0:
				sol_cons = copy.deepcopy(opt_problem._constraints)
				i = 0
				for key in sol_cons.keys():
					sol_cons[key].value = gg[i]
					i += 1
				#end
			else:
				sol_cons = {}
			#end
			
			sol_lambda = {}
			
			
			opt_problem.addSol(self.__class__.__name__, sol_name, objfunc, sol_time, 
				sol_evals, sol_inform, sol_vars, sol_objs, sol_cons, sol_options, 
				display_opts=disp_opts, Lambda=sol_lambda, Sensitivities=sens_type, 
				myrank=myrank, arguments=args, **kwargs)
			
		#end
		
		return ff, xx, sol_inform
コード例 #3
0
ファイル: pyMMA.py プロジェクト: swryan/pyOpt
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  disp_opts=False,
                  store_hst=False,
                  hot_start=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
		Run Optimizer (Optimize Routine)
		
		**Keyword arguments:**
		
		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD' 
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True 
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]
		
		Additional arguments and keyword arguments are passed to the objective function call.
		
		Documentation last updated:  February. 2, 2011 - Peter W. Jansen
		'''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyMMA - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        #end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print 'pyMMA: Parallel objective Function Analysis requires mpi4py'
            #end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            #end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        #end

        myrank = self.myrank

        #
        def_fname = self.options['IFILE'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # MMA - Objective/Constraint Values and Gradients Function
        #======================================================================
        def func(m, n, xval, f0val, df0dx, fval, dfdx):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = xval[group_ids[group][0]]
                    else:
                        xg[group] = xval[
                            group_ids[group][0]:group_ids[group][1]]
                    #end
                #end
                xn = xg
            else:
                xn = xval
            #end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function (Real Valued)
            fail = 0
            f = []
            g = []
            if (myrank == 0):
                if self.h_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        [f, g, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    #end
                #end
            #end

            if self.pll:
                self.h_start = Bcast(self.h_start, root=0)
            #end
            if self.h_start and self.pll:
                [f, g, fail] = Bcast([f, g, fail], root=0)
            elif not self.h_start:
                [f, g, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            #end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(xval, 'x')
                    log_file.write(f, 'obj')
                    log_file.write(g, 'con')
                    log_file.write(fail, 'fail')
                #end
            #end

            # Gradients
            if self.h_start:
                df = []
                dg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        df = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    #end
                #end
                if self.pll:
                    self.h_start = Bcast(self.h_start, root=0)
                #end
                if self.h_start and self.pll:
                    [df, dg] = Bcast([df, dg], root=0)
                #end
            #end

            if not self.h_start:

                #
                df, dg = gradient.getGrad(xval, group_ids, [f], g, *args,
                                          **kwargs)

            #end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(df, 'grad_obj')
                log_file.write(dg, 'grad_con')
            #end

            # Objective Assigment
            if isinstance(f, complex):
                f0val = f.astype(float)
            else:
                f0val = f
            #end

            # Constraints Assigment
            for i in xrange(len(opt_problem._constraints.keys())):
                if isinstance(g[i], complex):
                    fval[i] = g[i].astype(float)
                else:
                    fval[i] = g[i]
                #end
            #end

            # Gradients Assigment
            k = 0
            for i in xrange(len(opt_problem._variables.keys())):
                if isinstance(df[0, i], complex):
                    df0dx[i] = df[0, i].astype(float)
                else:
                    df0dx[i] = df[0, i]
                #end
                for jj in xrange(len(opt_problem._constraints.keys())):
                    if isinstance(dg[jj, i], complex):
                        dfdx[k] = dg[jj, i].astype(float)
                    else:
                        dfdx[k] = dg[jj, i]
                    #end
                    k += 1
                #end
            #end

            return f0val, df0dx, fval, dfdx

        # Variables Handling
        n = len(opt_problem._variables.keys())
        xmin = []
        xmax = []
        xval = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xmin.append(opt_problem._variables[key].lower)
                xmax.append(opt_problem._variables[key].upper)
                xval.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('MMA cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('MMA cannot handle discrete design variables')
            #end
        #end
        xmin = numpy.array(xmin)
        xmax = numpy.array(xmax)
        xval = numpy.array(xval)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            #end
        #end

        # Constraints Handling
        m = len(opt_problem._constraints.keys())
        neqc = 0
        #fval = []
        fmax = []
        if m > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    raise IOError('MMA cannot handle equality constraints')
                    #neqc += 1
                #end
                #fval.append(opt_problem._constraints[key].value)
                fmax.append(opt_problem._constraints[key].upper)
            #end
        #end
        #fval = numpy.array(fval)
        fmax = numpy.array(fmax)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        f0val = []
        for key in opt_problem._objectives.keys():
            f0val.append(opt_problem._objectives[key].value)
        #end
        f0val = numpy.array(f0val)

        # Setup argument list values

        xmma = numpy.zeros([n], numpy.float)

        # Space used internally by the program
        # for the asymptotes (xlow and xupp) and
        # computed bounds on x (alpha and beta)
        xlow = numpy.zeros([n], numpy.float)
        xupp = numpy.zeros([n], numpy.float)
        alfa = numpy.zeros([n], numpy.float)
        beta = numpy.zeros([n], numpy.float)

        # The objective and constraint function
        # values and space for the gradients
        fval = numpy.zeros([m], numpy.float)
        df0dx = numpy.zeros([n], numpy.float)
        dfdx = numpy.zeros([m * n], numpy.float)

        # Space for the coefficients and artificial
        # variables to be computed (set to default values)
        p = numpy.zeros([m * n], numpy.float)
        q = numpy.zeros([m * n], numpy.float)
        p0 = numpy.zeros([n], numpy.float)
        q0 = numpy.zeros([n], numpy.float)
        b = numpy.zeros([m], numpy.float)
        y = numpy.zeros([m], numpy.float)
        z = numpy.array([0.], numpy.float)
        a = numpy.zeros([m], numpy.float)
        c = 10000 * numpy.ones([m], numpy.float)

        # Space for the Lagrange multipliers (ulam)
        # the gradient of the dual objective function,
        # search direction, and Hessian of the dual objective
        ulam = numpy.ones([m], numpy.float)
        gradf = numpy.zeros([m], numpy.float)
        dsrch = numpy.zeros([m], numpy.float)
        hessf = numpy.zeros([m * (m + 1) / 2], numpy.float)

        # Specify that all variables are free to move
        iyfree = numpy.ones([m], numpy.int)

        #
        iter = numpy.array([0], numpy.int)
        maxit = numpy.array([self.options['MAXIT'][1]], numpy.int)
        geps = numpy.array([self.options['GEPS'][1]], numpy.float)
        dabobj = numpy.array([self.options['DABOBJ'][1]], numpy.float)
        delobj = numpy.array([self.options['DELOBJ'][1]], numpy.float)
        itrm = numpy.array([self.options['ITRM'][1]], numpy.int)
        inform = numpy.array([0], numpy.int)
        if (myrank == 0):
            iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
        else:
            iprint = numpy.array([0], numpy.int)
        iout = numpy.array([self.options['IOUT'][1]], numpy.int)
        ifile = self.options['IFILE'][1]
        if (myrank == 0):
            if (iprint >= 0):
                if os.path.isfile(ifile):
                    os.remove(ifile)
                #end
            #end
        #end

        #
        nfunc = numpy.array([0], numpy.int)

        # Run MMA
        t0 = time.time()
        mma.mma(n, m, iter, maxit, geps, dabobj, delobj, itrm, inform, xval,
                xmma, xmin, xmax, xlow, xupp, alfa, beta, f0val, fval, fmax,
                df0dx, dfdx, p, q, p0, q0, b, y, z, a, c, ulam, gradf, dsrch,
                hessf, iyfree, iprint, iout, ifile, nfunc, func)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                #end
            #end
        #end

        if (iprint > 0):
            mma.closeunit(self.options['IOUT'][1])
        #end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = inform[0]
        sol_inform['text'] = self.getInform(inform[0])

        if store_sol:

            sol_name = 'MMA Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if sol_options.has_key('defaults'):
                del sol_options['defaults']
            #end

            sol_evals = nfunc[0]

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xmma[i]
                i += 1
            #end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = f0val[i]
                i += 1
            #end

            if m > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = fval[i]
                    i += 1
                #end
            else:
                sol_cons = {}
            #end

            sol_lambda = {}

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        #end

        return f0val, xmma, sol_inform
コード例 #4
0
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  store_hst=False,
                  hot_start=False,
                  disp_opts=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
		Run Optimizer (Optimize Routine)
		
		**Keyword arguments:**
		
		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD' 
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True 
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]
		
		Additional arguments and keyword arguments are passed to the objective function call.
		
		Documentation last updated:  February. 2, 2011 - Ruben E. Perez
		'''

        #
        nec = 0
        nic = 0
        for key in opt_problem._constraints.keys():
            if opt_problem._constraints[key].type == 'e':
                nec += 1
            if opt_problem._constraints[key].type == 'i':
                nic += 1
            #end
        #end

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyFSQP - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        #end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print(
                    'pyFSQP: Parallel objective Function Analysis requires mpi4py'
                )
            #end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            #end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        #end

        myrank = self.myrank

        #
        def_fname = self.options['ifile'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # FSQP - Objective/Constraint Values Storage
        #======================================================================
        def eval(x):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    #end
                #end
                xn = xg
            else:
                xn = x
            #end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function (Real Valued)
            fail = 0
            f = []
            g = []
            if (myrank == 0):
                if self.hot_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        [f, g, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    #end
                #end
            #end

            if self.pll:
                self.hot_start = Bcast(self.hot_start, root=0)
            #end
            if self.hot_start and self.pll:
                [f, g, fail] = Bcast([f, g, fail], root=0)
            elif not self.hot_start:
                [f, g, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            #end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(f, 'obj')
                    log_file.write(g, 'con')
                    log_file.write(fail, 'fail')
                #end
            #end

            # Objective Assigment
            if isinstance(f, float):
                f = [f]
            #end
            for i in range(len(opt_problem._objectives.keys())):
                if isinstance(f[i], complex):
                    ff[i] = f[i].astype(float)
                else:
                    ff[i] = f[i]
                #end
            #end

            # Constraints Assigment
            i = 0
            for j in range(len(opt_problem._constraints.keys())):
                if isinstance(g[j], complex):
                    gg[i] = g[j].astype(float)
                else:
                    gg[i] = g[j]
                #end
                i += 1
            #end

            # Gradients
            if self.hot_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    #end
                #end
                if self.pll:
                    self.hot_start = Bcast(self.hot_start, root=0)
                #end
                if self.hot_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                #end
            #end

            if not self.hot_start:

                #
                dff, dgg = gradient.getGrad(x, group_ids, f, g, *args,
                                            **kwargs)

            #end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            #end

            # Store
            self.stored_data['x'] = copy.copy(x)
            self.stored_data['f'] = copy.copy(ff)
            self.stored_data['g'] = copy.copy(gg)
            self.stored_data['df'] = copy.copy(dff)
            self.stored_data['dg'] = copy.copy(dgg)

            return

        #======================================================================
        # FSQP - Objective Values Function
        #======================================================================
        def obj(nparam, j, x, fj):

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            #end

            ff = self.stored_data['f']
            if (nobj == 1):
                fj = ff
            else:
                if isinstance(ff, list):
                    ff = numpy.array(ff)
                #end
                fj = ff[j - 1]
            #end

            return fj

        #======================================================================
        # FSQP - Constraint Values Function
        #======================================================================
        def cntr(nparam, j, x, gj):

            # for given j, assign to gj the value of the jth constraint evaluated at x

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            #end

            gg = self.stored_data['g']
            if (j <= nic):
                jg = nec + (j - 1)
            else:
                jg = (j - 1) - nic
            #end
            gj = gg[jg]

            return gj

        #======================================================================
        # FSQP - Objective Gradients Function
        #======================================================================
        def gradobj(nparam, j, x, gradfj, obj):

            # assign to gradfj the gradient of the jth objective function evaluated at x

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            #end

            df = self.stored_data['df']
            for i in range(len(opt_problem._variables.keys())):
                gradfj[i] = df[j - 1, i]
            #end

            return gradfj

        #======================================================================
        # FSQP - Constraint Gradients Function
        #======================================================================
        def gradcntr(nparam, j, x, gradgj, obj):

            # assign to gradgj the gradient of the jth constraint evaluated at x

            if ((self.stored_data['x'] != x).any()):
                eval(x)
            #end

            dg = self.stored_data['dg']
            if (j <= nic):
                jg = nec + (j - 1)
            else:
                jg = (j - 1) - nic
            #end
            gradgj = dg[jg]

            return gradgj

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            xl.append(opt_problem._variables[key].lower)
            xu.append(opt_problem._variables[key].upper)
            xx.append(opt_problem._variables[key].value)
        #end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            #end
        #end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        neqc = 0
        gg = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    neqc += 1
                #end
                gg.append(opt_problem._constraints[key].value)
            #end
            gg = numpy.array(gg, numpy.float)
        else:
            gg = numpy.array([0], numpy.float)
        #end

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        #end
        ff = numpy.array(ff, numpy.float)

        # Setup argument list values
        nparam = numpy.array([nvar], numpy.int)
        nf = numpy.array([nobj], numpy.int)
        nineqn = numpy.array([ncon - neqc], numpy.int)
        nineq = nineqn
        neqn = numpy.array([neqc], numpy.int)
        neq = neqn
        mode = numpy.array([self.options['mode'][1]], numpy.int)
        if (myrank == 0):
            if (self.options['iprint'][1] >= 0):
                iprint = numpy.array([self.options['iprint'][1]], numpy.int)
            else:
                raise IOError('Incorrect Output Level Setting')
            #end
        else:
            iprint = numpy.array([0], numpy.int)
        #end
        iout = numpy.array([self.options['iout'][1]], numpy.int)
        ifile = self.options['ifile'][1]
        if (iprint > 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            #end
        #end
        miter = numpy.array([self.options['miter'][1]], numpy.int)
        inform = numpy.array([0], numpy.int)
        bigbnd = numpy.array([self.options['bigbnd'][1]], numpy.float)
        epstol = numpy.array([self.options['epstol'][1]], numpy.float)
        epsneq = numpy.array([self.options['epseqn'][1]], numpy.float)
        udelta = numpy.array([0], numpy.float)
        iwsizeM = 6 * nvar + 8 * max([1, ncon]) + 7 * max([1, nobj]) + 30
        iwsize = numpy.array([iwsizeM], numpy.int)
        iw = numpy.zeros([iwsize], numpy.float)
        nwsizeM = 4 * nvar**2 + 5 * max([1, ncon]) * nvar + 3 * max([
            1, nobj
        ]) * nvar + 26 * (nvar + max([1, nobj])) + 45 * max([1, ncon]) + 100
        nwsize = numpy.array([nwsizeM], numpy.int)
        w = numpy.zeros([nwsize], numpy.float)

        # Storage Arrays
        self.stored_data = {}
        self.stored_data['x'] = {}  #numpy.zeros([nvar],float)
        self.stored_data['f'] = {}  #numpy.zeros([nobj],float)
        self.stored_data['g'] = {}  #numpy.zeros([ncon],float)
        self.stored_data['df'] = {}  #numpy.zeros([nvar],float)
        self.stored_data['dg'] = {}  #numpy.zeros([ncon,nvar],float)

        # Run FSQP
        t0 = time.time()
        ffsqp.ffsqp(nparam, nf, nineqn, nineq, neqn, neq, mode, iprint, miter,
                    inform, bigbnd, epstol, epsneq, udelta, xl, xu, xx, ff, gg,
                    iw, iwsize, w, nwsize, obj, cntr, gradobj, gradcntr, iout,
                    ifile)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                #end
            #end
        #end

        if (iprint > 0):
            ffsqp.closeunit(self.options['iout'][1])
        #end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = inform[0]
        sol_inform['text'] = self.getInform(inform[0])

        if store_sol:

            sol_name = 'FSQP Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'defaults' in sol_options:
                del sol_options['defaults']
            #end

            sol_evals = 0

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            #end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            #end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = gg[i]
                    i += 1
                #end
            else:
                sol_cons = {}
            #end

            if ncon > 0:
                sol_lambda = numpy.zeros(ncon, float)
                for i in range(ncon):
                    sol_lambda[i] = w[nvar + i]
                #end
            else:
                sol_lambda = {}
            #end

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        #end

        return ff, xx, sol_inform
コード例 #5
0
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  disp_opts=False,
                  store_hst=False,
                  hot_start=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
        Run Optimizer (Optimize Routine)

        **Keyword arguments:**

        - opt_problem -> INST: Optimization instance
        - sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
        - store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
        - disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
        - store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
        - hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
        - sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
        - sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

        Additional arguments and keyword arguments are passed to the objective function call.

        Documentation last updated:  February. 2, 2011 - Peter W. Jansen
        '''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyNLPQL - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        # end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print 'pyNLPQL: Parallel objective Function Analysis requires mpi4py'
            # end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            # end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        # end

        myrank = self.myrank

        #
        def_fname = self.options['iFile'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        # ======================================================================
        # NLPQL - Objective/Constraint Values Function (Real Valued)
        # ======================================================================
        def nlfunc(m, me, mmax, n, f, g, x, active):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    # end
                # end
                xn = xg
            else:
                xn = x
            # end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            ff = []
            gg = []
            if (myrank == 0):
                if self.h_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        [ff, gg, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    # end
                    # end
            # end

            if self.pll:
                self.h_start = Bcast(self.h_start, root=0)
            # end
            if self.h_start and self.pll:
                [ff, gg, fail] = Bcast([ff, gg, fail], root=0)
            elif not self.h_start:
                [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            # end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')
                # end
            # end

            # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff
            # end

            # Constraints Assigment (negative gg as nlpql uses g(x) >= 0)
            for i in xrange(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = -gg[i].astype(float)
                else:
                    g[i] = -gg[i]
                # end
            # end

            return f, g

        # ======================================================================
        # NLPQL - Objective/Constraint Gradients Function
        # ======================================================================
        def nlgrad(m, me, mmax, n, f, g, df, dg, x, active, wa):

            if self.h_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    # end
                # end
                if self.pll:
                    self.h_start = Bcast(self.h_start, root=0)
                # end
                if self.h_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                # end
            # end

            if not self.h_start:
                #
                dff, dgg = gradient.getGrad(
                    x, group_ids, [f],
                    -g[0:len(opt_problem._constraints.keys())], *args,
                    **kwargs)

            # end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            # end

            # Gradient Assignment
            for i in xrange(len(opt_problem._variables.keys())):
                df[i] = dff[0, i]
                for j in xrange(len(opt_problem._constraints.keys())):
                    dg[j, i] = -dgg[j, i]
                # end
            # end

            return df, dg

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xl.append(opt_problem._variables[key].lower)
                xu.append(opt_problem._variables[key].upper)
                xx.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('NLPQL cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('NLPQL cannot handle discrete design variables')
            # end
        # end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            # end
        # end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        neqc = 0
        # gg = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    neqc += 1
                # end
                # gg.append(opt_problem._constraints[key].value)
                # end
        # end
        # gg = numpy.array(gg, numpy.float)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        # end
        ff = numpy.array(ff, numpy.float)

        # Setup argument list values
        mm = numpy.array([ncon], numpy.int)
        me = numpy.array([neqc], numpy.int)
        mmx = 200
        if (ncon >= mmx):
            mmx = ncon + 1
        # end
        mmax = numpy.array([mmx], numpy.int)
        nn = numpy.array([nvar], numpy.int)
        nmx = 200
        if (nvar >= nmx):
            nmx = nvar + 1
        # end
        nmax = numpy.array([nmx], numpy.int)
        mnn2 = numpy.array([mm[0] + nn[0] + nn[0] + 2], numpy.int)
        # xx = _ConcatenateVector(self.variables, 'value')
        # ff = self.objective.value
        gg = numpy.zeros([mmax], numpy.float)
        df = numpy.zeros([nmax], numpy.float)
        dg = numpy.zeros([mmax, nmax], numpy.float)
        uu = numpy.zeros([mnn2], numpy.float)
        # xl = _ConcatenateVector(self.variables, 'lower')
        # xu = _ConcatenateVector(self.variables, 'upper')
        cc = numpy.zeros([nmax, nmax], numpy.float)
        dd = numpy.zeros([nmax], numpy.float)
        acc = numpy.array([self.options['Accurancy'][1]], numpy.float)
        scbou = numpy.array([self.options['ScaleBound'][1]], numpy.float)
        maxfun = numpy.array([self.options['maxFun'][1]], numpy.int)
        maxit = numpy.array([self.options['maxIt'][1]], numpy.int)
        if (myrank == 0):
            if (self.options['iPrint'][1] >= 0
                    and self.options['iPrint'][1] <= 4):
                iprint = numpy.array([self.options['iPrint'][1]], numpy.int)
            else:
                raise IOError('Incorrect Output Level Setting')
            # end
        else:
            iprint = numpy.array([0], numpy.int)
        # end
        if (self.options['mode'][1] >= 0 and self.options['mode'][1] <= 18):
            mode = self.options['mode'][1]
        else:
            raise IOError('Incorrect Mode Setting')
        # end
        iout = self.options['iout'][1]
        ifile = self.options['iFile'][1]
        if (iprint > 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            # end
        # end
        ifail = numpy.array([0], numpy.int)
        lwa0 = 100000
        lwa1 = 4 * mmax + 4 * ncon + 19 * nvar + 55
        lwa2 = mmax * nvar + 4 * mmax + 4 * ncon + 18 * nvar + 55
        lwa3 = 3 / 2 * (nvar + 1) * (nvar + 1) + 10 * nvar + 2 * ncon + 10
        lwaM = max([lwa0, lwa1, lwa2, lwa3]) + lwa3
        lwa = numpy.array([lwaM], numpy.int)
        wa = numpy.zeros([lwa], numpy.float)
        lkwa = numpy.array([mmx + 2 * nmx + 20], numpy.int)
        kwa = numpy.zeros([lkwa], numpy.intc)
        lactiv = numpy.array([2 * mmx + 15], numpy.int)
        active = numpy.zeros([lactiv], numpy.bool)
        lmerit = numpy.array([self.options['lmerit'][1]], numpy.bool)
        lql = numpy.array([self.options['lql'][1]], numpy.bool)
        fmp = numpy.array([eps], numpy.float)

        # Run NLPQL
        t0 = time.time()
        nlpql.nlpql1(mm, me, mmax, nn, nmax, mnn2, xx, ff, gg, df, dg, uu, xl,
                     xu, cc, dd, acc, scbou, maxfun, maxit, iprint, mode, iout,
                     ifile, ifail, wa, lwa, kwa, lkwa, active, lactiv, lmerit,
                     lql, fmp, nlfunc, nlgrad)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                # end
                # end
        # end

        if (iprint > 0):
            nlpql.closeunit(self.options['iout'][1])
        # end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = ifail[0]
        sol_inform['text'] = self.getInform(ifail[0])

        if store_sol:

            sol_name = 'NLPQL Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if sol_options.has_key('defaults'):
                del sol_options['defaults']
            # end

            sol_evals = kwa[0] + kwa[1] * nvar

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            # end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            # end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = -gg[i]
                    i += 1
                # end
            else:
                sol_cons = {}
            # end

            if ncon > 0:
                sol_lambda = numpy.zeros(ncon, float)
                for i in xrange(ncon):
                    sol_lambda[i] = uu[i]
                # end
            else:
                sol_lambda = {}
            # end

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        # end

        return ff, xx, sol_inform
コード例 #6
0
ファイル: pyFILTERSD.py プロジェクト: victoralad/pyOpt
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  store_hst=False,
                  hot_start=False,
                  disp_opts=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
		Run Optimizer (Optimize Routine)

		**Keyword arguments:**

		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

		Additional arguments and keyword arguments are passed to the objective function call.

		Documentation last updated:  February. 2, 2013 - Ruben E. Perez
		'''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyFILTERSD - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        #end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print(
                    'pyFILTERSD: Parallel objective Function Analysis requires mpi4py'
                )
            #end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            #end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        #end

        myrank = self.myrank

        #
        def_fname = self.options['ifile'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # filterSD - Objective/Constraint Values Function (Real Valued)
        #======================================================================
        def functions(n, m, x, f, g, user, iuser):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    #end
                #end
                xn = xg
            else:
                xn = x
            #end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            ff = []
            gg = []
            if (myrank == 0):
                if self.hot_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        [ff, gg, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    #end
                #end
            #end

            if self.pll:
                self.hot_start = Bcast(self.hot_start, root=0)
            #end
            if self.hot_start and self.pll:
                [ff, gg, fail] = Bcast([ff, gg, fail], root=0)
            elif not self.hot_start:
                [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            #end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')
                #end
            #end

            # Store
            self.stored_data['x'] = copy.copy(x)
            self.stored_data['f'] = copy.copy(ff)
            self.stored_data['g'] = copy.copy(gg)

            # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff
            #end

            # Constraints Assigment
            for i in range(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = gg[i].astype(float)
                else:
                    g[i] = gg[i]
                #end
            #end

            return f, g

        #======================================================================
        # filterSD - Objective/Constraint Gradients Function
        #======================================================================
        def gradients(n, m, x, a, user, iuser):

            if ((self.stored_data['x'] != x).any()):
                f, g = functions(n, m, x, [], [], [], [])
            else:
                f = self.stored_data['f']
                g = self.stored_data['g']
            #end

            if self.hot_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    #end
                #end
                if self.pll:
                    self.hot_start = Bcast(self.hot_start, root=0)
                #end
                if self.hot_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                #end
            #end

            if not self.hot_start:

                #
                dff, dgg = gradient.getGrad(
                    x, group_ids, [f],
                    g[0:len(opt_problem._constraints.keys())], *args, **kwargs)

            #end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            #end

            # Gradient Assignment
            for i in range(len(opt_problem._variables.keys())):
                a[i, 0] = dff[0, i]
            #end
            for i in range(len(opt_problem._variables.keys())):
                for j in range(len(opt_problem._constraints.keys())):
                    a[i, j + 1] = dgg[j, i]
                #end
            #end

            return a

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            xl.append(opt_problem._variables[key].lower)
            xu.append(opt_problem._variables[key].upper)
            xx.append(opt_problem._variables[key].value)
        #end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            #end
        #end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        gg = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    raise IOError(
                        'FILTERSD cannot handle equality constraints')
                #end
                gg.append(opt_problem._constraints[key].value)
            #end
            gg = numpy.array(gg, numpy.float)
        else:
            ncon = 1
            gg = numpy.array([0], numpy.float)
        #end

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        #end
        ff = numpy.array(ff, numpy.float)

        # Setup argument list values
        nn = numpy.array([nvar], numpy.int)
        mm = numpy.array([ncon], numpy.int)
        al = numpy.zeros(mm, numpy.float)
        ubd = numpy.array([self.options['ubd'][1]], numpy.float)
        rho = numpy.array([self.options['rho'][1]], numpy.float)
        htol = numpy.array([self.options['htol'][1]], numpy.float)
        rgtol = numpy.array([self.options['rgtol'][1]], numpy.float)
        maxit = numpy.array([self.options['maxit'][1]], numpy.int)
        maxgr = numpy.array([self.options['maxgr'][1]], numpy.int)
        dchk = numpy.array([self.options['dchk'][1]], numpy.int)
        dtol = numpy.array([self.options['dtol'][1]], numpy.float)
        if (myrank == 0):
            if (self.options['iprint'][1] >= 0):
                iprint = numpy.array([self.options['iprint'][1]], numpy.int)
            else:
                raise IOError('Incorrect Output Level Setting')
            #end
        else:
            iprint = numpy.array([0], numpy.int)
        #end
        iout = numpy.array([self.options['iout'][1]], numpy.int)
        ifile = self.options['ifile'][1]
        if (iprint > 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            #end
        #end
        ifail = numpy.array([0], numpy.int)
        nfevs = numpy.array([0], numpy.int)
        ngevs = numpy.array([0], numpy.int)

        # Storage Arrays
        self.stored_data = {}
        self.stored_data['x'] = {}
        self.stored_data['f'] = {}
        self.stored_data['g'] = {}

        # Run filterSD
        t0 = time.time()
        filtersd.filtersd_wrap(nn, mm, xx, xl, xu, al, ff, gg, inf, ubd, rho,
                               htol, rgtol, maxit, maxgr, dchk, dtol, iprint,
                               iout, ifile, ifail, nfevs, ngevs, functions,
                               gradients)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                #end
            #end
        #end

        if (iprint > 0):
            filtersd.closeunit(self.options['iout'][1])
        #end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = ifail[0]
        sol_inform['text'] = self.getInform(ifail[0])

        if store_sol:

            sol_name = 'FILTERSD Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'defaults' in sol_options:
                del sol_options['defaults']
            #end

            sol_evals = nfevs[0] + ngevs[0] * nvar

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            #end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            #end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = gg[i]
                    i += 1
                #end
            else:
                sol_cons = {}
            #end

            if ncon > 0:
                sol_lambda = numpy.zeros(ncon, float)
                for i in range(ncon):
                    sol_lambda[i] = al[i]
                #end
            else:
                sol_lambda = {}
            #end

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

            time.sleep(0)
        #end

        return ff, xx, sol_inform
コード例 #7
0
ファイル: pySNOPT.py プロジェクト: rfenrich/pyOpt
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  disp_opts=False,
                  store_hst=False,
                  hot_start=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
        Run Optimizer (Optimize Routine)

        **Keyword arguments:**

        - opt_problem -> INST: Optimization instance
        - sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
        - store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
        - disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
        - store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
        - hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
        - sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
        - sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

        Additional arguments and keyword arguments are passed to the objective function call.

        Documentation last updated:  Feb. 2, 2011 - Peter W. Jansen
        '''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pySNOPT - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print(
                    'pySNOPT: Parallel objective Function Analysis requires mpi4py'
                )
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            elif (mpi4py.__version__[0] == '2'):
                Bcast = comm.bcast
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0

        myrank = self.myrank

        #
        def_fname = self.options['Print file'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # SNOPT-C - Objective/Constraint Values Function
        #======================================================================
        def snfuncgrag(mode, njac, x, f_obj, g_obj, f_con, g_con):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                xn = xg
            else:
                xn = x

            # Flush Output Files
            self.flushFiles()

            # Evaluate function values and derivatives together if required
            if sens_type == 'user':

                fail = 0
                if mode == 0:  # assign function values only

                    # Check history first
                    if self.hot_start:
                        [vals, hist_end
                         ] = hos_file.read(ident=['obj', 'con', 'fail'])
                        if hist_end:
                            self.hot_start = False
                            hos_file.close()
                        else:
                            [f_obj, f_con, fail] = [
                                vals['obj'][0][0], vals['con'][0],
                                int(vals['fail'][0][0])
                            ]

                    # Otherwise evaluate function
                    if not self.hot_start:
                        [f_obj, f_con, fail] = opt_problem.obj_fun(xn,
                                                                   ret='val',
                                                                   *args,
                                                                   **kwargs)

                    # Store History
                    if self.sto_hst:
                        log_file.write(x, 'x')
                        log_file.write(f_obj, 'obj')
                        log_file.write(f_con, 'con')
                        log_file.write(fail, 'fail')

                    if (fail == 1):
                        mode = -1
                        return mode

                    print(f_obj, f_con)
                    return mode, f_obj, g_obj, f_con, g_con

                elif mode == 1:  # assign gradients only

                    raise NotImplementedError(
                        'Assignment of gradients only is not implemented')

                elif mode == 2:  # assign values and gradients

                    # Check history first
                    if self.hot_start:
                        # Check for function values first
                        [vals, hist_end
                         ] = hos_file.read(ident=['obj', 'con', 'fail'])
                        if hist_end:
                            self.hot_start = False
                            hos_file.close()
                        else:
                            [f_obj, f_con, fail] = [
                                vals['obj'][0][0], vals['con'][0],
                                int(vals['fail'][0][0])
                            ]
                        if self.hot_start:  # Function values found, check for gradient values
                            [vals, hist_end
                             ] = hos_file.read(ident=['grad_obj', 'grad_con'])
                            if hist_end:
                                self.hot_start = False
                                hos_file.close()
                            else:
                                g_obj = vals['grad_obj'][0]
                                g_con = vals['grad_con'][0].reshape(
                                    (len(opt_problem._constraints.keys()),
                                     len(opt_problem._variables.keys())))

                    # If either values or gradients not found, evaluate function
                    if not self.hot_start:
                        [f_obj, f_con, g_obj, g_con,
                         fail] = opt_problem.obj_fun(xn,
                                                     ret='all',
                                                     *args,
                                                     **kwargs)

                    # Store History
                    if self.sto_hst:
                        log_file.write(x, 'x')
                        log_file.write(f_obj, 'obj')
                        log_file.write(f_con, 'con')
                        log_file.write(g_obj, 'grad_obj')
                        log_file.write(g_con, 'grad_con')
                        log_file.write(fail, 'fail')

                    if (fail == 1):
                        mode = -1
                        return mode
                    print(f_obj, f_con)
                    return mode, f_obj, g_obj, f_con, g_con

                else:
                    raise ValueError(
                        'Requested mode should be 0, 1, or 2, not %i' % mode)

            # Evaluate User Function
            fail = 0
            if (myrank == 0):
                if self.hot_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        [f_obj, f_con, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]

            if self.pll:
                self.hot_start = Bcast(self.hot_start, root=0)
            if self.hot_start and self.pll:
                [f_obj, f_con, fail] = Bcast([f_obj, f_con, fail], root=0)
            elif not self.hot_start:
                [f_obj, f_con, fail] = opt_problem.obj_fun(xn, *args, **kwargs)

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(f_obj, 'obj')
                    log_file.write(f_con, 'con')
                    log_file.write(fail, 'fail')

            #
            if (fail == 1):
                mode = -1
                return mode

            # Gradients
            if mode != 0 and self.hot_start:
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        g_obj = vals['grad_obj'][0]
                        g_con = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                if self.pll:
                    self.hot_start = Bcast(self.hot_start, root=0)
                if self.hot_start and self.pll:
                    [g_obj, g_con] = Bcast([g_obj, g_con], root=0)

            if mode != 0 and not self.hot_start:

                #
                dff, dgg = gradient.getGrad(x, group_ids, [f_obj], f_con,
                                            *args, **kwargs)

                #
                for i in range(len(opt_problem._variables.keys())):
                    g_obj[i] = dff[0, i]
                    for j in range(len(opt_problem._constraints.keys())):
                        g_con[j, i] = dgg[j, i]

            if (myrank == 0):
                if mode != 0 and self.sto_hst:
                    log_file.write(g_obj, 'grad_obj')
                    log_file.write(g_con, 'grad_con')

            # Objective Assigment
            if isinstance(f_obj, complex):
                f_obj = f_obj.astype(float)

            # Constraints Assigment
            for i in range(len(opt_problem._constraints.keys())):
                if isinstance(f_con[i], complex):
                    f_con[i] = f_con[i].astype(float)
            #print f_con
#            if not all(f_con):
#                print("not all f_con")
#                print f_con
#                f_con = [0]

            return mode, f_obj, g_obj, f_con, g_con

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        blx = []
        bux = []
        xs = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                blx.append(opt_problem._variables[key].lower)
                bux.append(opt_problem._variables[key].upper)
                xs.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('SNOPT cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('SNOPT cannot handle discrete design variables')
        blx = numpy.array(blx)
        bux = numpy.array(bux)
        xs = numpy.array(xs)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        blc = []
        buc = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if (opt_problem._constraints[key].type == 'e'):
                    blc.append(opt_problem._constraints[key].equal)
                    buc.append(opt_problem._constraints[key].equal)
                elif (opt_problem._constraints[key].type == 'i'):
                    blc.append(opt_problem._constraints[key].lower)
                    buc.append(opt_problem._constraints[key].upper)
        else:
            #if ((store_sol) and (myrank == 0)):
            #   print("Optimization Problem Does Not Have Constraints")
            #   print("Unconstrained Optimization Initiated")
            ncon = 1
            blc.append(-inf)
            buc.append(inf)
        blc = numpy.array(blc)
        buc = numpy.array(buc)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        ff = numpy.array(ff, numpy.float)

        # Initialize SNOPT
        iPrint = self.options['iPrint'][1]
        if (myrank != 0):
            iPrint = 0
        PrintFile = self.options['Print file'][1]
        if (iPrint != 0):
            if os.path.isfile(PrintFile):
                os.remove(PrintFile)
            ierror = snopt.openunit(iPrint, numpy.array(PrintFile),
                                    numpy.array('new'),
                                    numpy.array('sequential'))
            if (ierror != 0):
                raise IOError('Failed to properly open %s, ierror = %3d' %
                              (PrintFile, ierror))

        iSumm = self.options['iSumm'][1]
        if (myrank != 0):
            iSumm = 0
        SummFile = self.options['Summary file'][1]
        if (iSumm != 0):
            if os.path.isfile(SummFile):
                os.remove(SummFile)
            ierror = snopt.openunit(iSumm, numpy.array(SummFile),
                                    numpy.array('new'),
                                    numpy.array('sequential'))
            if (ierror != 0):
                raise IOError('Failed to properly open %s, ierror = %3d' %
                              (SummFile, ierror))
        lencw = 500
        leniw = 500 + 100 * (ncon + nvar)
        lenrw = 500 + 200 * (ncon + nvar)

        self.options['Total integer workspace'][1] = leniw
        self.options['Total real workspace'][1] = lenrw

        string = []
        for i in range(lencw):
            string.append('        ')
        cw = numpy.array(string, 'c')
        iw = numpy.zeros(leniw, 'i')
        rw = numpy.zeros(lenrw, numpy.float)
        snopt.sninit(iPrint, iSumm, cw, iw, rw)

        # Memory allocation
        if (opt_problem._linearConstraints):
            (aLr, aLc) = opt_problem._linearConstraints.matrix.shape
            ne = (ncon + aLr) * nvar
        else:
            ne = ncon * nvar
        nnCon = numpy.array(ncon, numpy.int)
        nnObj = numpy.array(nvar, numpy.int)
        nnJac = numpy.array(nvar, numpy.int)
        neGcon = nnCon * nnJac
        iExit = 0
        mincw, miniw, minrw, cw = snopt.snmemb(iExit, ncon, nvar, ne, neGcon,
                                               nnCon, nnJac, nnObj, cw, iw, rw)
        if ((minrw > lenrw) or (miniw > leniw) or (mincw > lencw)):
            if (mincw > lencw):
                lencw = mincw
                string = ""
                for i in range(lencw):
                    string = string + "        "
                # end for
                cw = numpy.transpose(
                    numpy.reshape(numpy.array(string), (lencw, 8)))
            if (miniw > leniw):
                leniw = miniw
                iw = numpy.zeros(leniw, 'i')
            if (minrw > lenrw):
                lenrw = minrw
                rw = numpy.zeros(lenrw, numpy.float)
            snopt.sninit(iPrint, iSumm, cw, iw, rw)

        # Set Options
        inform = numpy.array([-1], numpy.int)
        for i in range(len(self.set_options)):
            name = self.set_options[i][0]
            value = self.set_options[i][1]
            if isinstance(value, str):
                if (name == 'Start'):
                    if (value == 'Cold'):
                        snopt.snset('Cold start', iPrint, iSumm, inform, cw,
                                    iw, rw)
                    elif (value == 'Warm'):
                        snopt.snset('Warm start', iPrint, iSumm, inform, cw,
                                    iw, rw)
                elif (name == 'Problem Type'):
                    if (value == 'Minimize'):
                        snopt.snset('Minimize', iPrint, iSumm, inform, cw, iw,
                                    rw)
                    elif (value == 'Maximize'):
                        snopt.snset('Maximize', iPrint, iSumm, inform, cw, iw,
                                    rw)
                    elif (value == 'Feasible point'):
                        snopt.snset('Feasible point', iPrint, iSumm, inform,
                                    cw, iw, rw)
                elif (name == 'Print file'):
                    snopt.snset(name + ' ' + '%d' % (iPrint), iPrint, iSumm,
                                inform, cw, iw, rw)
                elif (name == 'Summary file'):
                    snopt.snset(name + ' ' + '%d' % (iSumm), iPrint, iSumm,
                                inform, cw, iw, rw)
                else:
                    snopt.snset(name + ' ' + value, iPrint, iSumm, inform, cw,
                                iw, rw)
            elif isinstance(value, float):
                snopt.snsetr(name, value, iPrint, iSumm, inform, cw, iw, rw)
            elif isinstance(value, int):
                if (name == 'iPrint') and iPrint == 0:
                    pass
                elif (name == 'iSumm') and iSumm == 0:
                    pass
                else:
                    snopt.snseti(name, value, iPrint, iSumm, inform, cw, iw,
                                 rw)
            elif isinstance(value, type(None)):
                snopt.snset(name, iPrint, iSumm, inform, cw, iw, rw)

        # Setup argument list values
        start = numpy.array(self.options['Start'][1])
        nName = numpy.array([1], numpy.int)
        nnCon = numpy.array(ncon, numpy.int)
        nnObj = numpy.array(nvar, numpy.int)
        nnJac = numpy.array(nvar, numpy.int)
        iObj = numpy.array([0], numpy.int)
        ObjAdd = numpy.array([0.], numpy.float)
        ProbNm = numpy.array(self.name)
        # Setup constraints
        if (opt_problem._linearConstraints):  # have linear constraints
            (aLr, aLc) = opt_problem._linearConstraints.matrix.shape
            neL = (ncon + aLr) * nvar
            a = numpy.zeros(neL, numpy.float)
            ina = ncon
            for j in range(nvar):
                inal = 0
                for i in range(ncon, ncon + aLr):
                    a[ina] = opt_problem._linearConstraints.matrix[inal, j]
                    ina = ina + 1
                    inal = inal + 1
                ina = ina + ncon
            ha = numpy.zeros(neL, 'i')
            ine = 0
            for j in range(nvar):
                for i in range(ncon + aLr):
                    ha[ine] = i + 1
                    ine = ine + 1
            ka = numpy.zeros(nvar + 1, 'i')
            ka[0] = 1
            for i in range(1, nvar + 1):
                ka[i] = ka[i - 1] + (ncon + aLr)
            bl = numpy.concatenate(
                (blx, blc, opt_problem._linearConstraints.lower))
            bu = numpy.concatenate(
                (bux, buc, opt_problem._linearConstraints.upper))
            xs = numpy.concatenate((xs, numpy.zeros(ncon + aLr, numpy.float)))
            hs = numpy.zeros(nvar + ncon + aLr, 'i')
            pi = numpy.zeros(ncon + aLr, numpy.float)
            rc = numpy.zeros(nvar + ncon + aLr, numpy.float)
        else:
            a = numpy.zeros(ne, numpy.float)
            ha = numpy.zeros(ne, 'i')
            ine = 0
            for j in range(nvar):
                for i in range(ncon):
                    ha[ine] = i + 1
                    ine = ine + 1
            ka = numpy.zeros(nvar + 1, 'i')
            ka[0] = 1
            for i in range(1, nvar + 1):
                ka[i] = ka[i - 1] + ncon
            bl = numpy.concatenate((blx, blc))
            bu = numpy.concatenate((bux, buc))
            xs = numpy.concatenate((xs, numpy.zeros(ncon, numpy.float)))
            hs = numpy.zeros(nvar + ncon, 'i')
            pi = numpy.zeros(ncon, numpy.float)
            rc = numpy.zeros(nvar + ncon, numpy.float)
        lencu = numpy.array([1], numpy.int)
        leniu = numpy.array([1], numpy.int)
        lenru = numpy.array([1], numpy.int)
        cu = numpy.array(["        "], 'c')
        iu = numpy.zeros([leniu[0]], numpy.int)
        ru = numpy.zeros([lenru[0]], numpy.float)
        Names = numpy.array(["        "], 'c')
        #inform = numpy.array([-1], numpy.int)
        mincw = numpy.array([0], numpy.int)
        miniw = numpy.array([0], numpy.int)
        minrw = numpy.array([0], numpy.int)
        nS = numpy.array([0], numpy.int)
        ninf = numpy.array([0], numpy.int)
        sinf = numpy.array([0.], numpy.float)

        # Run SNOPT
        t0 = time.time()
        snopt.snoptc(start, nnCon, nnObj, nnJac, iObj, ObjAdd, ProbNm,
                     snfuncgrag, a, ha, ka, bl, bu, Names, hs, xs, pi, rc,
                     inform, mincw, miniw, minrw, nS, ninf, sinf, ff, cu, iu,
                     ru, cw, iw, rw)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')

            if (iPrint != 0):
                snopt.closeunit(self.options['iPrint'][1])
            if (iSumm != 0):
                snopt.closeunit(self.options['iSumm'][1])
            if (self.options['New basis file'] != 0):
                snopt.closeunit(self.options['New basis file'][1])
            if (self.options['Dump file'] != 0):
                snopt.closeunit(self.options['Dump file'][1])

        # Store Results
        sol_inform = {}
        sol_inform['value'] = inform
        sol_inform['text'] = self.getInform(inform)

        if store_sol:

            sol_name = 'SNOPT Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'defaults' in sol_options:
                del sol_options['defaults']

            sol_evals = 0

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xs[i]
                i += 1

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1

            sol_cons = copy.deepcopy(opt_problem._constraints)
            i = 0
            for key in sol_cons.keys():
                sol_cons[key].value = xs[nvar + i]
                i += 1

            if ncon > 0:
                sol_lambda = numpy.zeros(ncon, float)
                for i in range(ncon):
                    sol_lambda[i] = pi[i]
            else:
                sol_lambda = {}

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        return ff, xs[0:nvar], sol_inform
コード例 #8
0
    def __solve__(self, opt_problem={}, sens_type='FD', store_sol=True, store_hst=False, hot_start=False,
                  disp_opts=False, sens_mode='', sens_step={}, *args, **kwargs):

        '''
        Run Optimizer (Optimize Routine)

        **Keyword arguments:**

        - opt_problem -> INST: Optimization instance
        - sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
        - store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
        - disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
        - store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
        - hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
        - sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
        - sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

        Additional arguments and keyword arguments are passed to the objective function call.

        Documentation last updated:  February. 2, 2011 - Peter W. Jansen
        '''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pySOLVOPT - Current implementation only allows single level parallelization, either 'POA' or 'pgc'")
        # end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print 'pySOLVOPT: Parallel objective Function Analysis requires mpi4py'
            # end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            # end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        # end

        myrank = self.myrank

        #
        def_fname = self.options['ifile'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step, *args, **kwargs)

        # ======================================================================
        # SOLVOPT - Objective/Constraint Values Storage
        # ======================================================================
        def soeval(x):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    # end
                # end
                xn = xg
            else:
                xn = x
            # end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            f = []
            g = []
            if (myrank == 0):
                if self.h_start:
                    [vals, hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        [f, g, fail] = [vals['obj'][0][0], vals['con'][0], int(vals['fail'][0][0])]
                    # end
                    # end
            # end

            if self.pll:
                self.h_start = Bcast(self.h_start, root=0)
            # end
            if self.h_start and self.pll:
                [f, g, fail] = Bcast([f, g, fail], root=0)
            elif not self.h_start:
                [f, g, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            # end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(f, 'obj')
                    log_file.write(g, 'con')
                    log_file.write(fail, 'fail')
                # end
            # end

            # Gradients
            if self.h_start:
                df = []
                dg = []
                if (myrank == 0):
                    [vals, hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        df = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()), len(opt_problem._variables.keys())))
                        dg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()), len(opt_problem._variables.keys())))
                    # end
                # end
                if self.pll:
                    self.h_start = Bcast(self.h_start, root=0)
                # end
                if self.h_start and self.pll:
                    [df, dg] = Bcast([df, dg], root=0)
                # end
            # end

            if not self.h_start:
                #
                df, dg = gradient.getGrad(x, group_ids, [f], g, *args, **kwargs)

            # end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(df, 'grad_obj')
                    log_file.write(dg, 'grad_con')
                # end
            # end

            # Objective Assigment
            if isinstance(f, complex):
                ff = f.astype(float)
            else:
                ff = f
            # end

            # Constraints Assigment
            i = 0
            j = 0
            for j in xrange(len(opt_problem._constraints.keys())):
                if isinstance(g[j], complex):
                    gg[i] = g[j].astype(float)
                else:
                    gg[i] = g[j]
                # end
                i += 1
            # end
            for key in opt_problem._variables.keys():
                if (opt_problem._variables[key].lower != -inf):
                    gg[i] = xl[j] - x[j]
                    i += 1
                # end
                if (opt_problem._variables[key].upper != inf):
                    gg[i] = x[j] - xu[j]
                    i += 1
                # end
            # end

            # Gradient Assignment
            df = df[0]
            dgg = numpy.zeros([len(opt_problem._variables.keys()) * 2, len(opt_problem._variables.keys())], 'd')
            i = len(opt_problem._constraints.keys())
            j = 0
            for key in opt_problem._variables.keys():
                if (opt_problem._variables[key].lower != -inf):
                    if (gg[i] > 0):
                        dgg[j, j] = -1
                    # end
                    i += 1
                # end
                if (opt_problem._variables[key].upper != inf):
                    if (gg[i] > 0):
                        dgg[j, j] = 1
                    # end
                    i += 1
                # end
                j += 1
            # end
            dg = numpy.concatenate((dg, dgg), axis=0)

            # Store
            self.stored_data['x'] = copy.copy(x)
            self.stored_data['f'] = copy.copy(ff)
            self.stored_data['g'] = copy.copy(gg)
            self.stored_data['df'] = copy.copy(df)
            self.stored_data['dg'] = copy.copy(dg)

            return

        # ======================================================================
        # SOLVOPT - Objective Value Function
        # ======================================================================
        def soobjf(n, x, f):

            if ((self.stored_data['x'] != x).any()):
                soeval(x)
            # end

            f = self.stored_data['f']

            return f

        # ======================================================================
        # SOLVOPT - Constraint Values Function
        # ======================================================================
        def soobjg(n, x, g):

            if ((self.stored_data['x'] != x).any()):
                soeval(x)
            # end

            # Constraints Maximal Residual
            maxg = numpy.zeros([len(self.stored_data['g'])], float)
            i = 0
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    maxg[i] = abs(self.stored_data['g'][i])
                    i += 1
                elif opt_problem._constraints[key].type == 'i':
                    maxg[i] = max(0, self.stored_data['g'][i])
                    i += 1
                # end
            # end
            for j in xrange(len(opt_problem._constraints), len(self.stored_data['g'])):
                maxg[i] = max(0, self.stored_data['g'][i])
                i += 1
            # end

            g = max(maxg)

            return g

        # ======================================================================
        # SOLVOPT - Objective Gradients Function
        # ======================================================================
        def sogrdf(n, x, df):

            if ((self.stored_data['x'] != x).any()):
                soeval(x)
            # end

            df = self.stored_data['df']

            return df

        # ======================================================================
        # SOLVOPT - Constraint Gradients Function
        # ======================================================================
        def sogrdg(n, x, dg):

            if ((self.stored_data['x'] != x).any()):
                soeval(x)
            # end

            # Constraints Maximal Residual
            maxg = numpy.zeros([len(self.stored_data['g'])], float)
            i = 0
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    maxg[i] = abs(self.stored_data['g'][i])
                    i += 1
                elif opt_problem._constraints[key].type == 'i':
                    maxg[i] = max(0, self.stored_data['g'][i])
                    i += 1
                # end
            # end
            for j in xrange(len(opt_problem._constraints), len(self.stored_data['g'])):
                maxg[i] = max(0, self.stored_data['g'][i])
                i += 1
            # end
            id = min(numpy.nonzero(maxg == max(maxg))[0])

            dg = self.stored_data['dg'][id]

            return dg

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xl.append(opt_problem._variables[key].lower)
                xu.append(opt_problem._variables[key].upper)
                xx.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('SOLVOPT cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('SOLVOPT cannot handle discrete design variables')
            # end
        # end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [k, k + group_len]
                k += group_len
            # end
        # end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        neqc = 0
        gg = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    neqc += 1
                # end
                # gg.append(opt_problem._constraints[key].value)
                gg.append(opt_problem._constraints[key].upper)
            # end
        # end
        nadd = 0
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].lower != -inf):
                gg.append(0)
                nadd += 1
            # end
            if (opt_problem._variables[key].upper != inf):
                gg.append(0)
                nadd += 1
            # end
        # end
        gg = numpy.array(gg, numpy.float)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        # end
        ff = numpy.array(ff, numpy.float)

        # Setup argument list values
        n = numpy.array([nvar], numpy.int)
        flg = numpy.array([True], numpy.bool)
        iprint = self.options['iprint'][1]
        if (myrank != 0):
            iprint = -1
        else:
            iprint = self.options['iprint'][1]
        # end
        options = numpy.zeros([13], numpy.float)
        options[0] = -1  # Minimize
        options[1] = self.options['xtol'][1]  # Variables Tolerance
        options[2] = self.options['ftol'][1]  # Objective Tolerance
        options[3] = self.options['maxit'][1]  # Maximum Number of Iterations
        options[4] = iprint  # Output Level
        options[5] = self.options['gtol'][1]  # Constraints Tolerance
        options[6] = self.options['spcdil'][1]  # Space Dilation
        options[7] = 1e-11  # LB FD Stepsize (NA as we provide our own sensitivities)
        flfc = numpy.array([True], numpy.bool)
        flgc = numpy.array([True], numpy.bool)
        iout = numpy.array([self.options['iout'][1]], numpy.int)
        ifile = self.options['ifile'][1]

        if (iprint >= 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            # end
        # end
        wb = numpy.zeros([nvar, nvar], numpy.float)
        wg = numpy.zeros([nvar], numpy.float)
        wg0 = numpy.zeros([nvar], numpy.float)
        wg1 = numpy.zeros([nvar], numpy.float)
        wgt = numpy.zeros([nvar], numpy.float)
        wgc = numpy.zeros([nvar], numpy.float)
        wz = numpy.zeros([nvar], numpy.float)
        wx1 = numpy.zeros([nvar], numpy.float)
        wxopt = numpy.zeros([nvar], numpy.float)
        wxrec = numpy.zeros([nvar], numpy.float)
        wgrec = numpy.zeros([nvar], numpy.float)
        wxx = numpy.zeros([nvar], numpy.float)
        wdeltax = numpy.zeros([nvar], numpy.float)
        widx = numpy.zeros([nvar], numpy.int)

        # Storage Arrays
        self.stored_data = {}
        self.stored_data['x'] = {}  # numpy.zeros([nvar],float)
        self.stored_data['f'] = {}  # numpy.zeros([nobj],float)
        self.stored_data['g'] = {}  # numpy.zeros([ncon+nadd],float)
        self.stored_data['df'] = {}  # numpy.zeros([nvar],float)
        self.stored_data['dg'] = {}  # numpy.zeros([ncon+nadd,nvar],float)

        # Run SOLVOPT
        t0 = time.time()
        solvopt.solvopt(n, xx, ff, soobjf, flg, sogrdf, options, flfc, soobjg, flgc, sogrdg, wb, wg, wg0, wg1, wgt, wgc,
                        wz, wx1, wxopt, wxrec, wgrec, wxx, wdeltax, widx, iout, ifile)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                # end
                # end
        # end

        if (iprint > 0):
            solvopt.closeunit(self.options['iout'][1])
        # end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = options[8]
        sol_inform['text'] = self.getInform(options[8])

        if store_sol:

            sol_name = 'SOLVOPT Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if sol_options.has_key('defaults'):
                del sol_options['defaults']
            # end

            sol_evals = options[9] + options[10]  # assumes cnst fevals and gevals are included in feval & geval

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            # end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            # end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = gg[i]
                    i += 1
                    if (i >= ncon):
                        break
                    # end
                    # end
            else:
                sol_cons = {}
            # end

            sol_lambda = {}

            opt_problem.addSol(self.__class__.__name__, sol_name, objfunc, sol_time,
                               sol_evals, sol_inform, sol_vars, sol_objs, sol_cons, sol_options,
                               display_opts=disp_opts, Lambda=sol_lambda, Sensitivities=sens_type,
                               myrank=myrank, arguments=args, **kwargs)

        # end

        return ff, xx, sol_inform
コード例 #9
0
ファイル: pySLSQP.py プロジェクト: JohnDN90/pyOpt-1
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  disp_opts=False,
                  store_hst=False,
                  hot_start=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
        Run Optimizer (Optimize Routine)

        **Keyword arguments:**

        - opt_problem -> INST: Optimization instance
        - sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
        - store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
        - disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
        - store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
        - hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
        - sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
        - sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

        Additional arguments and keyword arguments are passed to the objective function call.

        Documentation last updated:  February. 2, 2011 - Peter W. Jansen
        '''

        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pySLSQP - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print(
                    'pySLSQP: Parallel objective Function Analysis requires mpi4py'
                )

            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] >= '1'):
                Bcast = comm.bcast

            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0

        myrank = self.myrank

        def_fname = self.options['IFILE'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # SLSQP - Objective/Constraint Values Function
        #======================================================================
        def slfunc(m, me, la, n, f, g, x):
            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]

                xn = xg
            else:
                xn = x

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            ff = []
            gg = []
            if (myrank == 0):
                if self.hot_start:
                    [vals, hist_end] = hos_file.read(
                        ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        [ff, gg, fail] = [
                            vals['obj'][0][0], vals['con'][0], int(vals['fail']
                                                                   [0][0])
                        ]

            if self.pll:
                self.hot_start = Bcast(self.hot_start, root=0)

            if self.hot_start and self.pll:
                [ff, gg, fail] = Bcast([ff, gg, fail], root=0)
            elif not self.hot_start:
                [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')

            # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff

            # Constraints Assignment (negative gg as slsqp uses g(x) >= 0)
            for i in range(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = -gg[i].astype(float)
                else:
                    g[i] = -gg[i]

            return f, g

        #======================================================================
        # SLSQP - Objective/Constraint Gradients Function
        #======================================================================
        def slgrad(m, me, la, n, f, g, df, dg, x):
            if self.hot_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals, hist_end] = hos_file.read(
                        ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))

                if self.pll:
                    self.hot_start = Bcast(self.hot_start, root=0)

                if self.hot_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)

            if not self.hot_start:
                dff, dgg = gradient.getGrad(x, group_ids, [f], -g, *args, **
                                            kwargs)

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')

            # Gradient Assigment
            for i in range(len(opt_problem._variables.keys())):
                df[i] = dff[0, i]
                for jj in range(len(opt_problem._constraints.keys())):
                    dg[jj, i] = -dgg[jj, i]

            return df, dg

        # Variables Handling
        n = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xl.append(opt_problem._variables[key].lower)
                xu.append(opt_problem._variables[key].upper)
                xx.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('SLSQP cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('SLSQP cannot handle discrete design variables')

        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key][
                    'name']] = [k, k + group_len]
                k += group_len

        # Constraints Handling
        m = len(opt_problem._constraints.keys())
        meq = 0
        #gg = []
        if m > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    meq += 1

                #gg.append(opt_problem._constraints[key].value)

                #gg = numpy.array(gg,numpy.float)

                # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)

        ff = numpy.array(ff, numpy.float)

        # Setup argument list values
        la = max(m, 1)
        gg = numpy.zeros([la], numpy.float)
        n1 = numpy.array([n + 1], numpy.int)
        df = numpy.zeros([n + 1], numpy.float)
        dg = numpy.zeros([la, n + 1], numpy.float)
        acc = numpy.array([self.options['ACC'][1]], numpy.float)
        maxit = numpy.array([self.options['MAXIT'][1]], numpy.int)
        iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
        if (myrank != 0):
            iprint = -1
        else:
            iprint = self.options['IPRINT'][1]

        iout = numpy.array([self.options['IOUT'][1]], numpy.int)
        ifile = self.options['IFILE'][1]
        if (iprint >= 0):
            if os.path.isfile(ifile):
                os.remove(ifile)

        mode = numpy.array([0], numpy.int)
        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
        lwM = lsq + lsi + lsei + slsqpb + n + m
        lw = numpy.array([lwM], numpy.int)
        w = numpy.zeros(lw, numpy.float)
        ljwM = max(mineq, (n + 1) - meq)
        ljw = numpy.array([ljwM], numpy.int)
        jw = numpy.zeros(ljw, numpy.intc)
        nfunc = numpy.array([0], numpy.int)
        ngrad = numpy.array([0], numpy.int)

        # Run SLSQP
        t0 = time.time()
        slsqp.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)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')

        if (iprint > 0):
            slsqp.closeunit(self.options['IOUT'][1])

        # Store Results
        sol_inform = {}
        sol_inform['value'] = mode[0]
        sol_inform['text'] = self.getInform(mode[0])

        if store_sol:

            sol_name = 'SLSQP Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'defaults' in sol_options:
                del sol_options['defaults']

            sol_evals = 0

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1

            if m > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = -gg[i]
                    i += 1

            else:
                sol_cons = {}

            sol_lambda = {}

            opt_problem.addSol(
                self.__class__.__name__,
                sol_name,
                objfunc,
                sol_time,
                sol_evals,
                sol_inform,
                sol_vars,
                sol_objs,
                sol_cons,
                sol_options,
                display_opts=disp_opts,
                Lambda=sol_lambda,
                Sensitivities=sens_type,
                myrank=myrank,
                arguments=args,
                **kwargs)

        return ff, xx, sol_inform
コード例 #10
0
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  store_hst=False,
                  hot_start=False,
                  disp_opts=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
		Run Optimizer (Optimize Routine)
		
		**Keyword arguments:**
		
		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD' 
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True 
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]
		
		Additional arguments and keyword arguments are passed to the objective function call.
		
		Documentation last updated:  February. 2, 2013 - Peter W. Jansen
		'''

        #
        if ((self.pll_type != None) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyNLPQLP - Current implementation only allows single level parallelization, either 'POA', 'SMP', 'DPM' or 'pgc'"
            )
        #end

        if (self.pll_type != None) or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print(
                    'pyNLPQLP: Parallel objective Function Analysis or gradient calculation requires mpi4py'
                )
            #end
            comm = MPI.COMM_WORLD
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
                Barrier = comm.Barrier
                Send = comm.Send
                Recv = comm.Recv
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
                Barrier = comm.barrier
                Send = comm.send
                Recv = comm.recv
            #end
            self.pll = True
            if (self.pll_type == 'SPM'):
                nproc = comm.Get_size()
            else:
                nproc = 1
            #end
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            nproc = 1
            self.myrank = 0
        #end

        myrank = self.myrank

        #
        def_fname = self.options['IFILE'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # NLPQLP - Objective/Constraint Values Function
        #======================================================================
        def nlfunc(l, nmax, mmax, x, lactive, active, f, g):

            #
            if (self.pll_type == 'SPM'):
                mxi = myrank
            else:
                mxi = 0
            #end

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0], mxi]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1],
                                      mxi]
                    #end
                #end
                xn = xg
            else:
                xn = x[:-1, mxi]
            #end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            ff = []
            gg = []
            if (myrank == 0):
                if self.hot_start:
                    for proc in range(l):
                        [vals, hist_end
                         ] = hos_file.read(ident=['obj', 'con', 'fail'])
                        if hist_end:
                            self.hot_start = False
                            hos_file.close()
                        else:
                            [ff, gg, fail] = [
                                vals['obj'][0][0], vals['con'][0],
                                int(vals['fail'][0][0])
                            ]
                            f[proc] = ff
                            g[:, proc] = gg
                        #end
                    #end
                #end
            #end

            if self.pll:
                self.hot_start = Bcast(self.hot_start, root=0)
            #end
            if self.hot_start and self.pll:
                [f, g] = Bcast([f, g], root=0)
            elif not self.hot_start:
                [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)

                # Objective Assigment
                if isinstance(ff, complex):
                    f[mxi] = ff.astype(float)
                else:
                    f[mxi] = ff
                #end

                # Constraints Assigment (negative gg as nlpqlp uses g(x) >= 0)
                for i in range(len(opt_problem._constraints.keys())):
                    if isinstance(gg[i], complex):
                        g[i, mxi] = -gg[i].astype(float)
                    else:
                        g[i, mxi] = -gg[i]
                    #end
                #end

                if (self.pll_type == 'SPM'):
                    send_buf = {}
                    send_buf[myrank] = {'fi': f[mxi], 'gi': g[:, mxi]}
                    if myrank != 0:
                        Send(send_buf, dest=0)
                    else:
                        p_results = []
                        for proc in range(1, nproc):
                            p_results.append(Recv(source=proc))
                        #end
                    #end

                    if myrank == 0:
                        for proc in range(nproc - 1):
                            for i in p_results[proc].keys():
                                f[i] = p_results[proc][i]['fi']
                                g[:, i] = p_results[proc][i]['gi']
                            #end
                        #end
                    #end

                    [f, g] = Bcast([f, g], root=0)
                #end

            #end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    for proc in range(l):
                        log_file.write(x[:-1, proc], 'x')
                        log_file.write(f[proc], 'obj')
                        log_file.write(g[:, proc], 'con')
                        log_file.write(fail, 'fail')
                    #end
                #end
            #end

            return f, g

        #======================================================================
        # NLPQLP - Objective/Constraint Gradients Function
        #======================================================================
        def nlgrad(l, nmax, mmax, x, lactive, active, f, g, df, dg):

            if self.hot_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    #end
                #end
                if self.pll:
                    self.hot_start = Bcast(self.hot_start, root=0)
                #end
                if self.hot_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                #end
            #end

            if not self.hot_start:

                #
                dff, dgg = gradient.getGrad(
                    x[:-1, 0], group_ids, [f[0]],
                    -g[0:len(opt_problem._constraints.keys()), 0], *args,
                    **kwargs)

            #end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            #end

            # Gradient Assignment
            for i in range(len(opt_problem._variables.keys())):
                df[i] = dff[0, i]
                for j in range(len(opt_problem._constraints.keys())):
                    dg[j, i] = -dgg[j, i]
                #end
            #end

            return df, dg

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = numpy.zeros([max(2, nvar + 1)], numpy.float)
        xu = numpy.zeros([max(2, nvar + 1)], numpy.float)
        xx = numpy.zeros([max(2, nvar + 1), nproc], numpy.float)
        i = 0
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xl[i] = opt_problem._variables[key].lower
                xu[i] = opt_problem._variables[key].upper
                for proc in range(nproc):
                    xx[i, proc] = opt_problem._variables[key].value
                #end
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('NLPQLP cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('NLPQLP cannot handle discrete design variables')
            #end
            i += 1
        #end

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            #end
        #end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        neqc = 0
        gg = numpy.zeros([ncon, nproc], numpy.float)
        if ncon > 0:
            i = 0
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    neqc += 1
                #end
                if (self.pll == False):
                    gg[i, 0] = opt_problem._constraints[key].value
                else:
                    for proc in range(nproc):
                        gg[i, proc] = opt_problem._constraints[key].value
                    #end
                #end
                i += 1
            #end
        #end

        # Objective Handling
        objfunc = opt_problem.obj_fun
        if (len(opt_problem._objectives.keys()) > 1):
            raise IOError('NLPQLP cannot handle multi-objective problems')
        #end
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        #end
        ff = numpy.array(ff * nproc, numpy.float)

        # Setup argument list values
        ll = numpy.array([nproc], numpy.int)
        mm = numpy.array([ncon], numpy.int)
        me = numpy.array([neqc], numpy.int)
        mmax = numpy.array([max(1, mm)], numpy.int)
        nn = numpy.array([nvar], numpy.int)
        nmax = numpy.array([max(2, nn + 1)], numpy.int)
        mnn2 = numpy.array([mmax + nmax + nmax + 2], numpy.int)
        gg = numpy.zeros([mmax, ll], numpy.float)
        df = numpy.zeros([nmax], numpy.float)
        dg = numpy.zeros([mmax, nmax], numpy.float)
        uu = numpy.zeros([mnn2], numpy.float)
        cc = numpy.zeros([nmax, nmax], numpy.float)
        dd = numpy.zeros([nmax], numpy.float)
        acc = numpy.array([self.options['ACC'][1]], numpy.float)
        accqp = numpy.array([self.options['ACCQP'][1]], numpy.float)
        stpmin = numpy.array([self.options['STPMIN'][1]], numpy.float)
        maxfun = numpy.array([self.options['MAXFUN'][1]], numpy.int)
        maxit = numpy.array([self.options['MAXIT'][1]], numpy.int)
        if (nproc != 1):
            maxnm = numpy.array([max(1, min(50, nproc))], numpy.int)
        else:
            maxnm = numpy.array([0], numpy.int)
        #end
        rhob = self.options['RHOB'][1]
        if (self.options['MODE'][1] >= 0 and self.options['MODE'][1] <= 18):
            mode = self.options['MODE'][1]
        else:
            raise IOError('Incorrect Mode Setting')
        #end
        ifail = numpy.array([0], numpy.int)
        if (myrank == 0):
            if (self.options['IPRINT'][1] >= 0
                    and self.options['IPRINT'][1] <= 4):
                iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
            else:
                raise IOError('Incorrect Output Level Setting')
            #end
        else:
            iprint = numpy.array([0], numpy.int)
        #end
        iout = self.options['IOUT'][1]
        ifile = self.options['IFILE'][1]
        if (iprint > 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            #end
        #end
        lwa = numpy.array([
            23 * nmax + 4 * mmax + 3 * mmax + 150 + 3 * nmax * nmax / 2 +
            10 * nmax + nmax + mmax + 1
        ], numpy.int)
        wa = numpy.zeros([lwa], numpy.float)
        lkwa = numpy.array([25 + nmax], numpy.int)
        kwa = numpy.zeros([lkwa], numpy.intc)
        lactiv = numpy.array([2 * mmax + 10], numpy.int)
        active = numpy.zeros([lactiv], numpy.bool)
        lql = numpy.array([self.options['LQL'][1]], numpy.bool)
        nfun = numpy.array([0], numpy.int)
        ngrd = numpy.array([0], numpy.int)

        # Run NLPQLP
        t0 = time.time()
        xx, ff, gg, uu, nfun, ngrd = nlpqlp.nlpqlp_wrap(
            ll, mm, me, mmax, nn, nmax, mnn2, xx, ff, gg, df, dg, uu, xl, xu,
            cc, dd, acc, accqp, stpmin, maxfun, maxit, maxnm, rhob, mode,
            ifail, iprint, iout, ifile, wa, lwa, kwa, lkwa, active, lactiv,
            lql, nfun, ngrd, nlfunc, nlgrad)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                #end
            #end
        #end

        if (iprint > 0):
            nlpqlp.closeunit(self.options['IOUT'][1])
        #end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = ifail[0]
        sol_inform['text'] = self.getInform(ifail[0])

        if store_sol:

            sol_name = 'NLPQLP Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'defaults' in sol_options:
                del sol_options['defaults']
            #end

            sol_evals = nfun + ngrd * nvar

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i, 0]
                i += 1
            #end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[0]
                i += 1
            #end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = -gg[i, 0]
                    i += 1
                #end
            else:
                sol_cons = {}
            #end

            if ncon > 0:
                sol_lambda = numpy.zeros(ncon, float)
                for i in range(ncon):
                    sol_lambda[i] = uu[i]
                #end
            else:
                sol_lambda = {}
            #end

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        #end

        return ff, xx, sol_inform
コード例 #11
0
ファイル: pyALGENCAN.py プロジェクト: svn2github/pyopt
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  disp_opts=False,
                  store_hst=False,
                  hot_start=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
		Run Optimizer (Optimize Routine)
		
		**Keyword arguments:**
		
		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD' 
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True 
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]
		
		Additional arguments and keyword arguments are passed to the objective function call.
		
		Documentation last updated:  February. 2, 2011 - Peter W. Jansen
		'''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyALGENCAN - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        #end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print 'pyALGENCAN: Parallel objective Function Analysis requires mpi4py'
            #end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            #end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        #end

        myrank = self.myrank

        #
        def_fname = self.options['ifile'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #
        def evalf(n, x, f, flag):
            flag = -1
            return f, flag

        def evalg(n, x, g, flag):
            flag = -1
            return g, flag

        def evalh(n, x, hlin, hcol, hval, hnnz, flag):
            flag = -1
            return hlin, hcol, hval, hnnz, flag

        def evalc(n, x, ind, c, flag):
            flag = -1
            return c, flag

        def evaljac(n, x, ind, jcvar, jcval, jcnnz, flag):
            flag = -1
            return jcvar, jcval, jcnnz, flag

        def evalgjacp(n, x, g, m, p, q, work, gotj, flag):
            flag = -1
            return g, p, q, gotj, flag

        def evalhc(n, x, ind, hclin, hccol, hcval, hcnnz, flag):
            flag = -1
            return hclin, hccol, hcval, hcnnz, flag

        def evalhl(n, x, m, lmbda, scalef, scalec, hllin, hlcol, hlval, hlnnz,
                   flag):
            flag = -1
            return hllin, hlcol, hlval, hlnnz, flag

        def evalhlp(n, x, m, lmbda, sf, sc, p, hp, goth, flag):
            flag = -1
            return hp, goth, flag

        #======================================================================
        # ALGENCAN - Objective/Constraint Values Function
        #======================================================================
        def evalfc(n, x, f, m, g, flag):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    #end
                #end
                xn = xg
            else:
                xn = x
            #end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            flag = 0
            if (myrank == 0):
                if self.h_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        [ff, gg, flag] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    #end
                #end
            #end

            if self.pll:
                self.h_start = Bcast(self.h_start, root=0)
            #end
            if self.h_start and self.pll:
                [ff, gg, fail] = Bcast([ff, gg, fail], root=0)
            elif not self.h_start:
                [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            #end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')
                #end
            #end

            # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff
            #end

            # Constraints Assigment
            for i in xrange(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = gg[i].astype(float)
                else:
                    g[i] = gg[i]
                #end
            #end

            return f, g, fail

        #======================================================================
        # ALGENCAN - Objective/Constraint Gradients Function
        #======================================================================
        def evalgjac(n, x, jfval, m, jcfun, jcvar, jcval, jcnnz, flag):

            if self.h_start:
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.h_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    #end
                #end
                if self.pll:
                    self.h_start = Bcast(self.h_start, root=0)
                #end
                if self.h_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                #end
            #end

            if not self.h_start:

                [ff, gg, fail] = opt_problem.obj_fun(x, *args, **kwargs)
                dff, dgg = gradient.getGrad(x, group_ids, [ff], gg, *args,
                                            **kwargs)

            #end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            #end

            # Objective Gradient Assigment
            for i in xrange(len(opt_problem._variables.keys())):
                jfval[i] = dff[0, i]
            #end

            # Constraint Gradient Assigment
            jcnnz = 0
            for jj in xrange(len(opt_problem._constraints.keys())):
                for ii in xrange(len(opt_problem._variables.keys())):
                    jcfun[jcnnz] = jj + 1
                    jcvar[jcnnz] = ii + 1
                    jcval[jcnnz] = dgg[jj, ii]
                    jcnnz += 1
                #end
            #end

            return jfval, jcfun, jcvar, jcval, jcnnz, fail

        # Variables Handling
        n = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xl.append(opt_problem._variables[key].lower)
                xu.append(opt_problem._variables[key].upper)
                xx.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('NLPQL cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('NLPQL cannot handle discrete design variables')
            #end
        #end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            #end
        #end

        # Constraints Handling
        m = len(opt_problem._constraints.keys())
        equatn = []
        linear = []
        if m > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    equatn.append(True)
                elif opt_problem._constraints[key].type == 'i':
                    equatn.append(False)
                #end
                linear.append(False)
            #end
        else:
            raise IOError(
                'ALGENCAN support for unconstrained problems not implemented yet'
            )
        #end
        equatn = numpy.array(equatn)
        linear = numpy.array(linear)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        #end
        ff = numpy.array(ff)

        # Setup argument list values
        nn = numpy.array([n], numpy.int)
        mm = numpy.array([m], numpy.int)
        lm = numpy.zeros([m], numpy.float)
        coded = numpy.array([
            False, False, False, False, False, False, True, True, False, False
        ], numpy.bool)
        epsfeas = numpy.array([self.options['epsfeas'][1]], numpy.float)
        epsopt = numpy.array([self.options['epsopt'][1]], numpy.float)
        efacc = numpy.array([self.options['efacc'][1]], numpy.float)
        eoacc = numpy.array([self.options['eoacc'][1]], numpy.float)
        checkder = numpy.array([self.options['checkder'][1]], numpy.bool)
        iprint = numpy.array([self.options['iprint'][1]], numpy.int)
        if (myrank != 0):
            iprint = 0
        else:
            iprint = self.options['iprint'][1]
        #end
        ncomp = numpy.array([self.options['ncomp'][1]], numpy.int)

        ifile = self.options['ifile'][1]
        if (iprint >= 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            #end
        #end
        cnormu = numpy.array([0], numpy.float)
        snorm = numpy.array([0], numpy.float)
        nlpsupn = numpy.array([0], numpy.float)
        inform = numpy.array([0], numpy.int)

        # Run ALGENCAN
        t0 = time.time()
        algencan.algencan(epsfeas, epsopt, efacc, eoacc, iprint, ncomp, nn, xx,
                          xl, xu, mm, lm, equatn, linear, coded, checkder, ff,
                          cnormu, snorm, nlpsupn, inform, ifile, evalf, evalg,
                          evalh, evalc, evaljac, evalhc, evalfc, evalgjac,
                          evalgjacp, evalhl, evalhlp)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                #end
            #end
        #end

        if (iprint > 0):
            algencan.closeunit(10)
        #end

        #
        [fs, gg, fail] = opt_problem.obj_fun(xx, *args, **kwargs)

        # Store Results
        sol_inform = {}
        sol_inform['value'] = inform[0]
        sol_inform['text'] = self.getInform(inform[0])

        if store_sol:

            sol_name = 'ALGENCAN Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if sol_options.has_key('defaults'):
                del sol_options['defaults']
            #end

            sol_evals = 0

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            #end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            #end

            if m > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = gg[i]
                    i += 1
                #end
            else:
                sol_cons = {}
            #end

            sol_lambda = lm

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        #end

        return ff, xx, sol_inform
コード例 #12
0
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  disp_opts=False,
                  store_hst=False,
                  hot_start=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        """
        Run Optimizer (Optimize Routine)

        **Keyword arguments:**

        - opt_problem -> INST: Optimization instance
        - sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
        - store_sol -> BOOL: Store solution in Optimization class flag,
          *Default* = True
        - disp_opts -> BOOL: Flag to display options in solution text, *Default*
          = False
        - store_hst -> BOOL/STR: Flag/filename to store optimization history,
          *Default* = False
        - hot_start -> BOOL/STR: Flag/filename to read optimization history,
          *Default* = False
        - sens_mode -> STR: Flag for parallel gradient calculation, *Default* =
          ''
        - sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds
          to 1e-6 (FD), 1e-20(CS)]

        Documentation last updated:  Feb. 2, 2011 - Peter W. Jansen
        """

        self.pll = False
        self.myrank = 0

        myrank = self.myrank

        tmp_file = False
        def_fname = self.options['output_file'][1].split('.')[0]
        if isinstance(store_hst, str):
            if isinstance(hot_start, str):
                if (myrank == 0):
                    if (store_hst == hot_start):
                        hos_file = History(hot_start, 'r', self)
                        log_file = History(store_hst + '_tmp', 'w', self,
                                           opt_problem.name)
                        tmp_file = True
                    else:
                        hos_file = History(hot_start, 'r', self)
                        log_file = History(store_hst, 'w', self,
                                           opt_problem.name)

                self.sto_hst = True
                self.hot_start = True
            elif hot_start:
                if (myrank == 0):
                    hos_file = History(store_hst, 'r', self)
                    log_file = History(store_hst + '_tmp', 'w', self,
                                       opt_problem.name)
                    tmp_file = True

                self.sto_hst = True
                self.hot_start = True
            else:
                if (myrank == 0):
                    log_file = History(store_hst, 'w', self, opt_problem.name)

                self.sto_hst = True
                self.hot_start = False

        elif store_hst:
            if isinstance(hot_start, str):
                if (hot_start == def_fname):
                    if (myrank == 0):
                        hos_file = History(hot_start, 'r', self)
                        log_file = History(def_fname + '_tmp', 'w', self,
                                           opt_problem.name)
                        tmp_file = True

                else:
                    if (myrank == 0):
                        hos_file = History(hot_start, 'r', self)
                        log_file = History(def_fname, 'w', self,
                                           opt_problem.name)

                self.sto_hst = True
                self.hot_start = True
            elif hot_start:
                if (myrank == 0):
                    hos_file = History(def_fname, 'r', self)
                    log_file = History(def_fname + '_tmp', 'w', self,
                                       opt_problem.name)
                    tmp_file = True

                self.sto_hst = True
                self.hot_start = True
            else:
                if (myrank == 0):
                    log_file = History(def_fname, 'w', self, opt_problem.name)

                self.sto_hst = True
                self.hot_start = False

        else:
            self.sto_hst = False
            self.hot_start = False

        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        def eval_f(x, user_data=None):
            """IPOPT - Objective Value Function."""
            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]

                xn = xg
            else:
                xn = x

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            # if (myrank == 0):
            #    if self.hot_start:
            #        [vals,hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
            #        if hist_end:
            #            self.hot_start = False
            #            hos_file.close()
            #        else:
            #            [ff,gg,fail] = [vals['obj'][0][0],vals['con'][0],int(vals['fail'][0][0])]
            #
            #

            # if self.pll:
            #    self.hot_start = Bcast(self.hot_start,root=0)

            # if self.hot_start and self.pll:
            #    [ff,gg,fail] = Bcast([ff,gg,fail],root=0)
            # else:
            [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')

                # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff

            # Constraints Assigment
            g = numpy.zeros(len(opt_problem._constraints.keys()))
            for i in range(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = gg[i].astype(float)
                else:
                    g[i] = gg[i]

            return f

        def eval_g(x, user_data=None):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]

                xn = xg
            else:
                xn = x

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            #            if (myrank == 0):
            #                if self.hot_start:
            #                    [vals,hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
            #                    if hist_end:
            #                        self.hot_start = False
            #                        hos_file.close()
            #                    else:
            #                        [ff,gg,fail] = [vals['obj'][0][0],vals['con'][0],int(vals['fail'][0][0])]

            # if self.pll:
            #   self.hot_start = Bcast(self.hot_start,root=0)

            # if self.hot_start and self.pll:
            #    [ff,gg,fail] = Bcast([ff,gg,fail],root=0)
            # else:
            [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')

                # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff

            # Constraints Assigment
            g = numpy.zeros(len(opt_problem._constraints.keys()))
            for i in range(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = gg[i].astype(float)
                else:
                    g[i] = gg[i]

            return g

        def eval_grad_f(x, user_data=None):
            """IPOPT - Objective/Constraint Gradients Function."""
            # if self.hot_start:
            #    if (myrank == 0):
            #        [vals,hist_end] = hos_file.read(ident=['grad_obj','grad_con'])
            #        if hist_end:
            #            self.hot_start = False
            #            hos_file.close()
            #        else:
            #            dff = vals['grad_obj'][0].reshape((len(opt_problem._objectives.keys()),len(opt_problem._variables.keys())))
            #            dgg = vals['grad_con'][0].reshape((len(opt_problem._constraints.keys()),len(opt_problem._variables.keys())))
            #
            #
            #    if self.pll:
            #        self.hot_start = Bcast(self.hot_start,root=0)
            #
            #    if self.hot_start and self.pll:
            #        [dff,dgg] = Bcast([dff,dgg],root=0)
            #

            # if not self.hot_start:

            [f, g, fail] = opt_problem.obj_fun(x, *args, **kwargs)
            dff, dgg = gradient.getGrad(x, group_ids, [f], g, *args, **kwargs)

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')

            # Gradient Assignment
            df = numpy.zeros(len(opt_problem._variables.keys()))

            for i in range(len(opt_problem._variables.keys())):
                df[i] = dff[0, i]

            return df

        def eval_grad_g(x, flag, user_data=None):

            # if self.hot_start:
            #    if (myrank == 0):
            #        [vals,hist_end] = hos_file.read(ident=['grad_obj','grad_con'])
            #        if hist_end:
            #            self.hot_start = False
            #            hos_file.close()
            #        else:
            #            dff = vals['grad_obj'][0].reshape((len(opt_problem._objectives.keys()),len(opt_problem._variables.keys())))
            #            dgg = vals['grad_con'][0].reshape((len(opt_problem._constraints.keys()),len(opt_problem._variables.keys())))
            #
            #
            #    if self.pll:
            #        self.hot_start = Bcast(self.hot_start,root=0)
            #
            #    if self.hot_start and self.pll:
            #        [dff,dgg] = Bcast([dff,dgg],root=0)
            #

            # if not self.hot_start:

            if flag:
                a = numpy.zeros(
                    len(opt_problem._variables.keys()) *
                    len(opt_problem._constraints.keys()), int)
                b = numpy.zeros(
                    len(opt_problem._variables.keys()) *
                    len(opt_problem._constraints.keys()), int)

                for i in range(len(opt_problem._constraints.keys())):
                    for j in range(len(opt_problem._variables.keys())):
                        a[i * len(opt_problem._variables.keys()) + j] = i
                        b[i * len(opt_problem._variables.keys()) + j] = j
                return (a, b)

            else:
                [f, g, fail] = opt_problem.obj_fun(x, *args, **kwargs)
                dff, dgg = gradient.getGrad(x, group_ids, [f], g, *args,
                                            **kwargs)

                # Store History
                if self.sto_hst and (myrank == 0):
                    log_file.write(dff, 'grad_obj')
                    log_file.write(dgg, 'grad_con')

                # Gradient Assignment
                a = numpy.zeros([
                    len(opt_problem._variables.keys()) *
                    len(opt_problem._constraints.keys())
                ])
                for i in range(len(opt_problem._constraints.keys())):
                    for j in range(len(opt_problem._variables.keys())):
                        a[i * len(opt_problem._variables.keys()) +
                          j] = dgg[i, j]

                return a

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            if opt_problem._variables[key].type == 'c':
                xl.append(opt_problem._variables[key].lower)
                xu.append(opt_problem._variables[key].upper)
                xx.append(opt_problem._variables[key].value)
            elif opt_problem._variables[key].type == 'i':
                raise IOError('IPOPT cannot handle integer design variables')
            elif opt_problem._variables[key].type == 'd':
                raise IOError('IPOPT cannot handle discrete design variables')

        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key][
                    'name']] = [k, k + group_len]
                k += group_len

            # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        blc = []
        buc = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'e':
                    blc.append(opt_problem._constraints[key].equal)
                    buc.append(opt_problem._constraints[key].equal)
                elif opt_problem._constraints[key].type == 'i':
                    blc.append(opt_problem._constraints[key].lower)
                    buc.append(opt_problem._constraints[key].upper)

        else:
            if ((store_sol) and (myrank == 0)):
                print("Optimization Problem Does Not Have Constraints\n")
                print("Unconstrained Optimization Initiated\n")

            ncon = 1
            blc.append(-inf)
            buc.append(inf)

        blc = numpy.array(blc)
        buc = numpy.array(buc)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)

        ff = numpy.array(ff)

        # Create an IPOPT instance problem
        nnzj = nvar * ncon
        nnzh = nvar * nvar
        ipopt = pyipopt.create(nvar, xl, xu, ncon, blc, buc, nnzj, nnzh,
                               eval_f, eval_grad_f, eval_g, eval_grad_g)

        # Setup Options
        optionss = self.options.copy()
        del optionss['defaults']

        for i in optionss:
            if not self.options['defaults'][i][1] == optionss[i][1]:
                if self.options[i][0].__name__ == 'int':
                    ipopt.int_option(i, self.options[i][1])

                if self.options[i][0].__name__ == 'float':
                    ipopt.num_option(i, self.options[i][1])

                if self.options[i][0].__name__ == 'str':
                    ipopt.str_option(i, self.options[i][1])

        # Run IPOPT

        t0 = time.time()
        r = ipopt.solve(xx)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')

        ipopt.close()

        # Store Results
        sol_inform = {}
        print(r)
        sol_inform['value'] = r[-1]  # ifail[0]
        sol_inform['text'] = self.getInform(r[-1])  # self.getInform(ifail[0])

        if store_sol:
            sol_name = 'IPOPT Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'default' in sol_options:
                del sol_options['defaults']

            sol_evals = 0

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            x = r[0]
            for key in sol_vars.keys():
                sol_vars[key].value = x[i]
                i += 1

            sol_objs = copy.deepcopy(opt_problem._objectives)
            sol_objs[0].value = r[4]

            sol_cons = {}

            if ncon > 0:
                sol_lambda = r[3]
            else:
                sol_lambda = {}

            opt_problem.addSol(
                self.__class__.__name__,
                sol_name,
                objfunc,
                sol_time,
                sol_evals,
                sol_inform,
                sol_vars,
                sol_objs,
                sol_cons,
                sol_options,
                display_opts=disp_opts,
                Lambda=sol_lambda,
                Sensitivities=sens_type,
                myrank=myrank,
                arguments=args,
                **kwargs)

        return ff, xx, sol_inform  # ifail[0]
コード例 #13
0
ファイル: pyCONMIN.py プロジェクト: tong0711/pyOpt
	def __solve__(self, opt_problem={}, sens_type='FD', store_sol=True, store_hst=False, hot_start=False, disp_opts=False, sens_mode='', sens_step={}, *args, **kwargs):

		'''
		Run Optimizer (Optimize Routine)

		**Keyword arguments:**

		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD'
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]

		Additional arguments and keyword arguments are passed to the objective function call

		Documentation last updated:  February. 2, 2011 - Ruben E. Perez
		'''

		#
		if ((self.poa) and (sens_mode.lower() == 'pgc')):
			raise NotImplementedError("pyCONMIN- Current implementation only allows single level parallelization, either 'POA' or 'pgc'")

		if self.poa or (sens_mode.lower() == 'pgc'):
			try:
				import mpi4py
				from mpi4py import MPI
			except ImportError:
				print('pyCONMIN: Parallel objective Function Analysis requires mpi4py')
			comm = MPI.COMM_WORLD
			nproc = comm.Get_size()
			if (mpi4py.__version__[0] == '0'):
				Bcast = comm.Bcast
			elif (mpi4py.__version__[0] == '1'):
				Bcast = comm.bcast
			self.pll = True
			self.myrank = comm.Get_rank()
		else:
			self.pll = False
			self.myrank = 0

		myrank = self.myrank

		#
		def_fname = self.options['IFILE'][1].split('.')[0]
		hos_file, log_file, tmp_file = self._setHistory(opt_problem.name, store_hst, hot_start, def_fname)

		#
		gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step, *args, **kwargs)


		#======================================================================
		# CONMIN - Objective/Constraint Values Function
		#======================================================================
		def cnmnfun(n1,n2,x,f,g):

			# Variables Groups Handling
			if opt_problem.use_groups:
				xg = {}
				for group in group_ids.keys():
					if (group_ids[group][1]-group_ids[group][0] == 1):
						xg[group] = x[group_ids[group][0]]
					else:
						xg[group] = x[group_ids[group][0]:group_ids[group][1]]
				xn = xg
			else:
				xn = x

			# Flush Output Files
			self.flushFiles()

			# Evaluate User Function
			fail = 0
			ff = []
			gg = []
			if (myrank == 0):
				if self.hot_start:
					[vals,hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
					if hist_end:
						self.hot_start = False
						hos_file.close()
					else:
						[ff,gg,fail] = [vals['obj'][0][0],vals['con'][0],int(vals['fail'][0][0])]

			if self.pll:
				self.hot_start = Bcast(self.hot_start,root=0)
			if self.hot_start and self.pll:
				[ff,gg,fail] = Bcast([ff,gg,fail],root=0)
			elif not self.hot_start:
				[ff,gg,fail] = opt_problem.obj_fun(xn, *args, **kwargs)

			# Store History
			if (myrank == 0):
				if self.sto_hst:
					log_file.write(x,'x')
					log_file.write(ff,'obj')
					log_file.write(gg,'con')
					log_file.write(fail,'fail')

			# Objective Assigment
			if isinstance(ff,complex):
				f = ff.astype(float)
			else:
				f = ff

			# Constraints Assigment
			for i in range(len(opt_problem._constraints.keys())):
				if isinstance(gg[i],complex):
					g[i] = gg[i].astype(float)
				else:
					g[i] = gg[i]

			return f,g


		#======================================================================
		# CONMIN - Objective/Constraint Gradients Function
		#======================================================================
		def cnmngrd(n1,n2,x,f,g,ct,df,a,ic,nac):

			#
			nac = 0
			for j in range(len(opt_problem._constraints.keys())):
				if (g[j] >= ct):
					ic[nac] = j + 1
					nac += 1

			#
			if self.hot_start:
				dff = []
				dgg = []
				if (myrank == 0):
					[vals,hist_end] = hos_file.read(ident=['grad_obj','grad_con'])
					if hist_end:
						self.hot_start = False
						hos_file.close()
					else:
						dff = vals['grad_obj'][0].reshape((len(opt_problem._objectives.keys()),len(opt_problem._variables.keys())))
						dgg = vals['grad_con'][0].reshape((len(opt_problem._constraints.keys()),len(opt_problem._variables.keys())))
				if self.pll:
					self.hot_start = Bcast(self.hot_start,root=0)
				if self.hot_start and self.pll:
					[dff,dgg] = Bcast([dff,dgg],root=0)

			if not self.hot_start:

				#
				dff,dgg = gradient.getGrad(x, group_ids, [f], g[0:len(opt_problem._constraints.keys())], *args, **kwargs)


			# Store History
			if self.sto_hst and (myrank == 0):
				log_file.write(dff,'grad_obj')
				log_file.write(dgg,'grad_con')

			# Gradient Assignment
			for i in range(len(opt_problem._variables.keys())):
				df[i] = dff[0,i]
				for j in range(len(opt_problem._constraints.keys())):
					for k in range(nac):
						if (ic[k] == j+1):
							a[i,k] = dgg[j,i]

			return df,a,ic,nac



		# Variables Handling
		nvar = len(opt_problem._variables.keys())
		xl = []
		xu = []
		xx = []
		for key in opt_problem._variables.keys():
			if (opt_problem._variables[key].type == 'c'):
				xl.append(opt_problem._variables[key].lower)
				xu.append(opt_problem._variables[key].upper)
				xx.append(opt_problem._variables[key].value)
			elif (opt_problem._variables[key].type == 'i'):
				raise IOError('CONMIN cannot handle integer design variables')
			elif (opt_problem._variables[key].type == 'd'):
				raise IOError('CONMIN cannot handle discrete design variables')
		xl = numpy.array(xl)
		xu = numpy.array(xu)
		xx = numpy.array(xx)

		# Variables Groups Handling
		group_ids = {}
		if opt_problem.use_groups:
			k = 0
			for key in opt_problem._vargroups.keys():
				group_len = len(opt_problem._vargroups[key]['ids'])
				group_ids[opt_problem._vargroups[key]['name']] = [k,k+group_len]
				k += group_len

		# Constraints Handling
		ncon = len(opt_problem._constraints.keys())
		#neqc = 0
		#gg = []
		if ncon > 0:
			for key in opt_problem._constraints.keys():
				if opt_problem._constraints[key].type == 'e':
					raise IOError('CONMIN cannot handle equality constraints')
					#neqc += 1
				#gg.append(opt_problem._constraints[key].value)
		#gg = numpy.array(gg)

		# Objective Handling
		objfunc = opt_problem.obj_fun
		nobj = len(opt_problem._objectives.keys())
		ff = []
		for key in opt_problem._objectives.keys():
			ff.append(opt_problem._objectives[key].value)
		ff = numpy.array(ff,numpy.float)


		# Setup argument list values
		ndv = numpy.array([nvar], numpy.int)
		ncn = numpy.array([ncon], numpy.int)
		nn1 = numpy.array([ndv[0]+2], numpy.int)
		nn2 = numpy.array([ncn[0]+2*ndv[0]], numpy.int)
		#nn3 = numpy.array([numpy.min(100,ndv[0]+1)], numpy.int)
		nn3 = numpy.array([numpy.max([nn2[0],ndv[0]])], numpy.int)
		#nn4 = numpy.array([numpy.max(nn3[0],ndv[0])], numpy.int)
		nn4 = numpy.array([numpy.max([nn2[0],ndv[0]])], numpy.int)
		nn5 = numpy.array([2*nn4[0]], numpy.int)
		if ncon > 0:
			gg = numpy.zeros(ncn, numpy.float)
		else:
			gg = numpy.array([0], numpy.float)
		if (myrank == 0):
			if (self.options['IPRINT'][1]>=0 and self.options['IPRINT'][1]<=4):
				iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
			else:
				raise IOError('Incorrect Output Level Setting')
		else:
			iprint = numpy.array([0], numpy.int)
		iout = numpy.array([self.options['IOUT'][1]], numpy.int)
		ifile = self.options['IFILE'][1]
		if (iprint > 0):
			if os.path.isfile(ifile):
				os.remove(ifile)
		itmax = numpy.array([self.options['ITMAX'][1]], numpy.int)
		delfun = numpy.array([self.options['DELFUN'][1]], numpy.float)

		finit,ginit = cnmnfun([],[],xx,ff,gg)
		dabfun = numpy.array([self.options['DABFUN'][1]*finit], numpy.float)

		itrm = numpy.array([self.options['ITRM'][1]], numpy.int)
		nfeasct = numpy.array([self.options['NFEASCT'][1]], numpy.int)
		nfdg = numpy.array(1, numpy.int)

		nfun = numpy.array([0], numpy.int)
		ngrd = numpy.array([0], numpy.int)


		# Run CONMIN
		t0 = time.time()
		conmin.conmin(ndv,ncn,xx,xl,xu,ff,gg,nn1,nn2,nn3,nn4,nn5,
			iprint,iout,ifile,itmax,delfun,dabfun,itrm,nfeasct,
			nfdg,nfun,ngrd,cnmnfun,cnmngrd)
		sol_time = time.time() - t0

		if (myrank == 0):
			if self.sto_hst:
				log_file.close()
				if tmp_file:
					hos_file.close()
					name = hos_file.filename
					os.remove(name+'.cue')
					os.remove(name+'.bin')
					os.rename(name+'_tmp.cue',name+'.cue')
					os.rename(name+'_tmp.bin',name+'.bin')

		if (iprint > 0):
			conmin.closeunit(self.options['IOUT'][1])


		# Store Results
		sol_inform = {}
		sol_inform['value'] = []	#ifail[0]
		sol_inform['text'] = {}		#self.getInform(ifail[0])

		if store_sol:

			sol_name = 'CONMIN Solution to ' + opt_problem.name

			sol_options = copy.copy(self.options)
			if 'defaults' in sol_options:
				del sol_options['defaults']

			sol_evals = nfun[0] + ngrd[0]*nvar

			sol_vars = copy.deepcopy(opt_problem._variables)
			i = 0
			for key in sol_vars.keys():
				sol_vars[key].value = xx[i]
				i += 1

			sol_objs = copy.deepcopy(opt_problem._objectives)
			i = 0
			for key in sol_objs.keys():
				sol_objs[key].value = ff[i]
				i += 1

			if ncon > 0:
				sol_cons = copy.deepcopy(opt_problem._constraints)
				i = 0
				for key in sol_cons.keys():
					sol_cons[key].value = gg[i]
					i += 1
			else:
				sol_cons = {}

			sol_lambda = {}


			opt_problem.addSol(self.__class__.__name__, sol_name, objfunc, sol_time,
				sol_evals, sol_inform, sol_vars, sol_objs, sol_cons, sol_options,
				display_opts=disp_opts, Lambda=sol_lambda, Sensitivities=sens_type,
				myrank=myrank, arguments=args, **kwargs)


		return ff, xx, sol_inform #ifail[0]
コード例 #14
0
ファイル: pyMMFD.py プロジェクト: victoralad/pyOpt
    def __solve__(self,
                  opt_problem={},
                  sens_type='FD',
                  store_sol=True,
                  store_hst=False,
                  hot_start=False,
                  disp_opts=False,
                  sens_mode='',
                  sens_step={},
                  *args,
                  **kwargs):
        '''
		Run Optimizer (Optimize Routine)
		
		**Keyword arguments:**
		
		- opt_problem -> INST: Optimization instance
		- sens_type -> STR/FUNC: Gradient type, *Default* = 'FD' 
		- store_sol -> BOOL: Store solution in Optimization class flag, *Default* = True 
		- disp_opts -> BOOL: Flag to display options in solution text, *Default* = False
		- store_hst -> BOOL/STR: Flag/filename to store optimization history, *Default* = False
		- hot_start -> BOOL/STR: Flag/filename to read optimization history, *Default* = False
		- sens_mode -> STR: Flag for parallel gradient calculation, *Default* = ''
		- sens_step -> FLOAT: Sensitivity setp size, *Default* = {} [corresponds to 1e-6 (FD), 1e-20(CS)]
		
		Additional arguments and keyword arguments are passed to the objective function call.
		
		Documentation last updated:  February. 2, 2011 - Ruben E. Perez
		'''

        #
        if ((self.poa) and (sens_mode.lower() == 'pgc')):
            raise NotImplementedError(
                "pyMMFD - Current implementation only allows single level parallelization, either 'POA' or 'pgc'"
            )
        #end

        if self.poa or (sens_mode.lower() == 'pgc'):
            try:
                import mpi4py
                from mpi4py import MPI
            except ImportError:
                print(
                    'pyMMFD: Parallel objective Function Analysis requires mpi4py'
                )
            #end
            comm = MPI.COMM_WORLD
            nproc = comm.Get_size()
            if (mpi4py.__version__[0] == '0'):
                Bcast = comm.Bcast
            elif (mpi4py.__version__[0] == '1'):
                Bcast = comm.bcast
            #end
            self.pll = True
            self.myrank = comm.Get_rank()
        else:
            self.pll = False
            self.myrank = 0
        #end

        myrank = self.myrank

        #
        def_fname = self.options['IFILE'][1].split('.')[0]
        hos_file, log_file, tmp_file = self._setHistory(
            opt_problem.name, store_hst, hot_start, def_fname)

        #
        gradient = Gradient(opt_problem, sens_type, sens_mode, sens_step,
                            *args, **kwargs)

        #======================================================================
        # MMFD - Objective/Constraint Values Function
        #======================================================================
        def mmfdfun(nv, nc, x, f, g):

            # Variables Groups Handling
            if opt_problem.use_groups:
                xg = {}
                for group in group_ids.keys():
                    if (group_ids[group][1] - group_ids[group][0] == 1):
                        xg[group] = x[group_ids[group][0]]
                    else:
                        xg[group] = x[group_ids[group][0]:group_ids[group][1]]
                    #end
                #end
                xn = xg
            else:
                xn = x
            #end

            # Flush Output Files
            self.flushFiles()

            # Evaluate User Function
            fail = 0
            ff = []
            gg = []
            if (myrank == 0):
                if self.hot_start:
                    [vals,
                     hist_end] = hos_file.read(ident=['obj', 'con', 'fail'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        [ff, gg, fail] = [
                            vals['obj'][0][0], vals['con'][0],
                            int(vals['fail'][0][0])
                        ]
                    #end
                #end
            #end

            if self.pll:
                self.hot_start = Bcast(self.hot_start, root=0)
            #end
            if self.hot_start and self.pll:
                [ff, gg, fail] = Bcast([ff, gg, fail], root=0)
            elif not self.hot_start:
                [ff, gg, fail] = opt_problem.obj_fun(xn, *args, **kwargs)
            #end

            # Store History
            if (myrank == 0):
                if self.sto_hst:
                    log_file.write(x, 'x')
                    log_file.write(ff, 'obj')
                    log_file.write(gg, 'con')
                    log_file.write(fail, 'fail')
                #end
            #end

            # Objective Assigment
            if isinstance(ff, complex):
                f = ff.astype(float)
            else:
                f = ff
            #end

            # Constraints Assigment
            for i in range(len(opt_problem._constraints.keys())):
                if isinstance(gg[i], complex):
                    g[i] = gg[i].astype(float)
                else:
                    g[i] = gg[i]
                #end
            #end

            return f, g

        #======================================================================
        # MMFD - Objective/Constraint Gradients Function
        #======================================================================
        def mmfdgrd(nv, nc, x, f, g, df, dg):

            if self.hot_start:
                dff = []
                dgg = []
                if (myrank == 0):
                    [vals,
                     hist_end] = hos_file.read(ident=['grad_obj', 'grad_con'])
                    if hist_end:
                        self.hot_start = False
                        hos_file.close()
                    else:
                        dff = vals['grad_obj'][0].reshape(
                            (len(opt_problem._objectives.keys()),
                             len(opt_problem._variables.keys())))
                        dgg = vals['grad_con'][0].reshape(
                            (len(opt_problem._constraints.keys()),
                             len(opt_problem._variables.keys())))
                    #end
                #end
                if self.pll:
                    self.hot_start = Bcast(self.hot_start, root=0)
                #end
                if self.hot_start and self.pll:
                    [dff, dgg] = Bcast([dff, dgg], root=0)
                #end
            #end

            if not self.hot_start:

                #
                dff, dgg = gradient.getGrad(x, group_ids, [f], g, *args,
                                            **kwargs)

            #end

            # Store History
            if self.sto_hst and (myrank == 0):
                log_file.write(dff, 'grad_obj')
                log_file.write(dgg, 'grad_con')
            #end

            # Gradient Assignment
            for i in range(len(opt_problem._variables.keys())):
                df[i] = dff[0, i]
                for j in range(len(opt_problem._constraints.keys())):
                    dg[i, j] = dgg[j, i]
                #end
            #end

            return df, dg

        # Variables Handling
        nvar = len(opt_problem._variables.keys())
        xl = []
        xu = []
        xx = []
        for key in opt_problem._variables.keys():
            if (opt_problem._variables[key].type == 'c'):
                xl.append(opt_problem._variables[key].lower)
                xu.append(opt_problem._variables[key].upper)
                xx.append(opt_problem._variables[key].value)
            elif (opt_problem._variables[key].type == 'i'):
                raise IOError('MMFD cannot handle integer design variables')
            elif (opt_problem._variables[key].type == 'd'):
                raise IOError('MMFD cannot handle discrete design variables')
            #end
        #end
        xl = numpy.array(xl)
        xu = numpy.array(xu)
        xx = numpy.array(xx)

        # Variables Groups Handling
        group_ids = {}
        if opt_problem.use_groups:
            k = 0
            for key in opt_problem._vargroups.keys():
                group_len = len(opt_problem._vargroups[key]['ids'])
                group_ids[opt_problem._vargroups[key]['name']] = [
                    k, k + group_len
                ]
                k += group_len
            #end
        #end

        # Constraints Handling
        ncon = len(opt_problem._constraints.keys())
        neqc = 0
        gg = []
        idg = []
        if ncon > 0:
            for key in opt_problem._constraints.keys():
                if opt_problem._constraints[key].type == 'i':
                    idg.append(1)
                elif opt_problem._constraints[key].type == 'e':
                    idg.append(-1)
                #end
                gg.append(opt_problem._constraints[key].value)
            #end
        else:
            raise IOError(
                'MMFD support for unconstrained problems not implemented yet')
        #end
        gg = numpy.array(gg)
        idg = numpy.array(idg, numpy.int)

        # Objective Handling
        objfunc = opt_problem.obj_fun
        nobj = len(opt_problem._objectives.keys())
        ff = []
        for key in opt_problem._objectives.keys():
            ff.append(opt_problem._objectives[key].value)
        #end
        ff = numpy.array(ff)

        # Setup argument list values
        ndv = numpy.array([nvar], numpy.int)
        ncn = numpy.array([ncon], numpy.int)
        if (self.options['IOPT'][1] >= 0 and self.options['IOPT'][1] <= 1):
            iopt = numpy.array([self.options['IOPT'][1]], numpy.int)
        else:
            raise IOError('Incorrect Feasible Directions Approach')
        #end
        if (self.options['IONED'][1] >= 0 and self.options['IONED'][1] <= 3):
            ioned = numpy.array([self.options['IONED'][1]], numpy.int)
        else:
            raise IOError('Incorrect One-Dimensional Search Method')
        #end
        if (myrank == 0):
            if (self.options['IPRINT'][1] >= 0
                    and self.options['IPRINT'][1] <= 2):
                iprint = numpy.array([self.options['IPRINT'][1]], numpy.int)
            else:
                raise IOError('Incorrect Output Level Setting')
            #end
        else:
            iprint = numpy.array([0], numpy.int)
        #end
        #iout = numpy.array([self.options['IOUT'][1]], numpy.int)
        ifile = self.options['IFILE'][1]
        if (iprint > 0):
            if os.path.isfile(ifile):
                os.remove(ifile)
            #end
        #end
        ct = numpy.array([self.options['CT'][1]], numpy.float)
        ctmin = numpy.array([self.options['CTMIN'][1]], numpy.float)

        finit, ginit = mmfdfun([], [], xx, ff, gg)
        dabobj = numpy.array([self.options['DABOBJ'][1] * finit], numpy.float)

        delobj = numpy.array([self.options['DELOBJ'][1]], numpy.float)
        thetaz = numpy.array([self.options['THETAZ'][1]], numpy.float)
        pmlt = numpy.array([self.options['PMLT'][1]], numpy.float)
        itmax = numpy.array([self.options['ITMAX'][1]], numpy.int)
        itrmop = numpy.array([self.options['ITRMOP'][1]], numpy.int)
        nrwk0 = 500
        nrwk1 = 10 * (2 * nvar + ncon)
        nrwk2 = (ncon + 2 * nvar + 3)
        nrwk3 = (ncon + 2 * nvar) * ((ncon + 2 * nvar) / 2 + 1)
        nrwkS = nrwk0 + nrwk1 + nrwk2 + nrwk3
        nrwk = numpy.array([nrwkS], numpy.int)
        wk = numpy.zeros([nrwk], numpy.float)
        nriwk = numpy.array([nrwkS], numpy.int)
        iwk = numpy.zeros([nriwk], numpy.int)

        nfun = numpy.array([0], numpy.int)
        ngrd = numpy.array([0], numpy.int)

        # Run MMFD
        t0 = time.time()
        mmfd.mmfd(iopt, ioned, iprint, ndv, ncn, xx, xl, xu, ff, gg, idg, wk,
                  nrwk, iwk, nriwk, ifile, ct, ctmin, dabobj, delobj, thetaz,
                  pmlt, itmax, itrmop, nfun, ngrd, mmfdfun, mmfdgrd)
        sol_time = time.time() - t0

        if (myrank == 0):
            if self.sto_hst:
                log_file.close()
                if tmp_file:
                    hos_file.close()
                    name = hos_file.filename
                    os.remove(name + '.cue')
                    os.remove(name + '.bin')
                    os.rename(name + '_tmp.cue', name + '.cue')
                    os.rename(name + '_tmp.bin', name + '.bin')
                #end
            #end
        #end

        if (iprint > 0):
            #	mmfd.closeunit(self.options['IOUT'][1])
            mmfd.closeunit(6)
        #end

        # Store Results
        sol_inform = {}
        sol_inform['value'] = []
        sol_inform['text'] = {}

        if store_sol:

            sol_name = 'MMFD Solution to ' + opt_problem.name

            sol_options = copy.copy(self.options)
            if 'defaults' in sol_options:
                del sol_options['defaults']
            #end

            sol_evals = nfun[0] + ngrd[0] * nvar

            sol_vars = copy.deepcopy(opt_problem._variables)
            i = 0
            for key in sol_vars.keys():
                sol_vars[key].value = xx[i]
                i += 1
            #end

            sol_objs = copy.deepcopy(opt_problem._objectives)
            i = 0
            for key in sol_objs.keys():
                sol_objs[key].value = ff[i]
                i += 1
            #end

            if ncon > 0:
                sol_cons = copy.deepcopy(opt_problem._constraints)
                i = 0
                for key in sol_cons.keys():
                    sol_cons[key].value = gg[i]
                    i += 1
                #end
            else:
                sol_cons = {}
            #end

            sol_lambda = {}

            opt_problem.addSol(self.__class__.__name__,
                               sol_name,
                               objfunc,
                               sol_time,
                               sol_evals,
                               sol_inform,
                               sol_vars,
                               sol_objs,
                               sol_cons,
                               sol_options,
                               display_opts=disp_opts,
                               Lambda=sol_lambda,
                               Sensitivities=sens_type,
                               myrank=myrank,
                               arguments=args,
                               **kwargs)

        #end

        return ff, xx, sol_inform