Ejemplo n.º 1
0
def get_res(nofun, morefun, nexp, xhat, ft, constraintT, sign=1., rank=0):
    w = np.ones(ft.shape)
    w[0] *= 10.
    print('rank {}'.format(rank), end='')
    res = so.minimize(lambda z: nl.norm(np.multiply(w,
                                                    nofun(z) - ft))**2,
                      xhat,
                      bounds=[(None, None), (2**-11, None)] * nexp,
                      jac='2-point',
                      hess=so.BFGS(),
                      method='trust-constr',
                      options={
                          'verbose': 1,
                          'maxiter': 2048,
                          'xtol': 1e-8
                      })
    print('rank {}'.format(rank), end='')
    res = so.minimize(lambda z: nl.norm(np.multiply(w,
                                                    nofun(z) - ft))**2,
                      xhat,
                      constraints=so.NonlinearConstraint(
                          lambda z: sign *
                          (nofun(z, constraintT) - morefun(constraintT)), 0,
                          np.inf),
                      bounds=[(None, None), (2**-11, None)] * nexp,
                      jac='2-point',
                      hess=so.BFGS(),
                      method='trust-constr',
                      options={
                          'verbose': 1,
                          'maxiter': 2048,
                          'xtol': 1e-8
                      })
    i = 1
    while res.status == 3 or res.fun > 5e-1:
        print('rank {}'.format(rank), end='')
        alpha = 1. / np.sqrt(++i)
        res = so.minimize(lambda z: nl.norm(np.multiply(w,
                                                        nofun(z) - ft))**2,
                          res.x * (1. - alpha) +
                          alpha * nr.uniform(-1e-1, 1e-1, xhat.shape[0]),
                          constraints=so.NonlinearConstraint(
                              lambda z: sign *
                              (nofun(z, constraintT) - morefun(constraintT)),
                              0, np.inf),
                          bounds=[(None, None), (2**-11, None)] * nexp,
                          jac='2-point',
                          hess=so.BFGS(),
                          method='trust-constr',
                          options={
                              'verbose': 1,
                              'maxiter': 2048,
                              'xtol': 1e-8
                          })
    return res
Ejemplo n.º 2
0
    def optimize(self, graph, demands, initial=None):
        options = {
            'maxiter': self.max_iters,
            'factorization_method': 'SVDFactorization'
        }

        initial = initial if initial is not None else np.zeros(shape=(graph.number_of_edges(),), dtype=float)
        bounds = optimize.Bounds(lb=0, ub=np.inf)
        constraint = self._constraint(graph, demands)

        flows_per_iter = []

        def callback(x, state):
            flows_per_iter.append(x)
            return False

        hess = optimize.BFGS()
        result = optimize.minimize(fun=self.cost_fn,
                                   x0=initial,
                                   callback=callback,
                                   bounds=bounds,
                                   method='trust-constr',
                                   constraints=[constraint],
                                   jac='2-point',
                                   hess=hess,
                                   options=options)

        return np.array(flows_per_iter), result
Ejemplo n.º 3
0
    def __init__(self,
                 game,
                 dist_measures=None,
                 dist_tensor=None,
                 messages=None,
                 epsilon=1e-4):
        """
        Parameters
        ----------

        dist_measures: A list of integers with the distortions from
        self.dist_tensor to be considered
        """
        RDT.__init__(self, game, dist_tensor, epsilon)
        self.states = len(self.pmf)
        if dist_measures:
            self.dist_measures = dist_measures
        else:
            self.dist_measures = range(self.dist_tensor.shape[0])
        if messages:
            self.messages = messages
        else:
            self.messages = self.states
        self.enc_dec_length = self.messages * (self.states + self.outcomes)
        # length of the encoder_decoder vector we optimize over.
        self.hess = opt.BFGS(exception_strategy='skip_update')
        self.bounds = opt.Bounds(0, 1)
        self.constraint = self.lin_constraint(self.dist_measures)
        self.default_enc_dec_init = self.enc_dec_init()
Ejemplo n.º 4
0
def run_optim_fixed_x0(datavox):
    res = opt.minimize(func_vox_ls,
                       x0=x0,
                       args=(b, bd, datavox),
                       jac='3-point',
                       hess=opt.BFGS(),
                       method='trust-constr',
                       constraints=[cons, fa_cons])
    return res
Ejemplo n.º 5
0
    def add_nonlinear_eq_con(self, poly=None, custom=None):
        """
        Adds nonlinear inequality constraints :math:`g(x) = value` (for poly option) or :math:`g(x) = 0` (for function option) to the optimisation routine.
        Only ``trust-constr`` and ``SLSQP`` methods can handle equality constraints. If poly object is providedin the poly dictionary, gradients and Hessians will be computed automatically.

        :param dict poly: Arguments for poly dictionary.
            :param Poly poly: An instance of the Poly class.
            :param float value: Value of the nonlinear constraint.
        :param dict custom: Additional custom callable arguments.
            :callable function: The constraint function to be called.
            :callable jac_function: The gradient (or derivative) of the constraint.
            :callable hess_function: The Hessian of the constraint function.
        """
        assert self.method == 'trust-constr' or 'SLSQP'
        assert poly is not None or custom is not None
        if poly is not None:
            assert 'value' in poly
            value = poly['value']
            g = poly.get_polyfit_function()
            jac = poly.get_polyfit_grad_function()
            hess = poly.get_polyfit_hess_function()
            constraint = lambda x: np.asscalar(g(x))
            constraint_deriv = lambda x: jac(x)[:, 0]
            constraint_hess = lambda x, v: hess(x)[:, :, 0]
            if self.method == 'trust-constr':
                self.constraints.append(optimize.NonlinearConstraint(constraint, value, value, jac=constraint_deriv, \
                             hess=constraint_hess))
            else:
                self.constraints.append({'type':'eq', 'fun': lambda x: constraint(x) - value, \
                             'jac': constraint_deriv})
        elif custom is not None:
            assert 'function' in custom
            constraint = custom['function']
            if 'jac_function' in custom:
                constraint_deriv = custom['jac_function']
            else:
                constraint_deriv = '2-point'
            if 'hess_function' in custom:
                constraint_hess = lambda x, v: custom['hess_function'](x)
            else:
                constraint_hess = optimize.BFGS()
            if self.method == 'trust-constr':
                self.constraints.append(optimize.NonlinearConstraint(constraint, 0.0, 0.0, jac=constraint_deriv, \
                         hess=constraint_hess))
            else:
                if 'jac_function' in custom:
                    self.constraints.append({
                        'type': 'eq',
                        'fun': constraint,
                        'jac': constraint_deriv
                    })
                else:
                    self.constraints.append({'type': 'eq', 'fun': constraint})
Ejemplo n.º 6
0
 def _optimizer(obj_func, initial_theta, bounds, method):
     constraints = [
         optimize.LinearConstraint(np.eye(initial_theta.shape[0]),
                                   bounds[:, 0], bounds[:, 1])
     ]
     res = optimize.minimize(
         lambda theta: obj_func(theta=theta, eval_gradient=False),
         initial_theta,
         constraints=constraints,
         method=method,
         jac=lambda theta: obj_func(theta=theta, eval_gradient=True)[1],
         hess=optimize.BFGS(),
         options={'gtol': 1e-6})
     return res.x, res.fun
Ejemplo n.º 7
0
def nonlinearConstraintBuilder(model,
                               min_scaling_aspect_val,
                               max_scaling_aspect_val,
                               forecasted_metric_val,
                               compose_model_input,
                               jacobian='2-point',
                               hessian=opt.BFGS()):

    cons_f = nonlinearConstraintFunctionBuilder(model, forecasted_metric_val,
                                                compose_model_input)

    return opt.NonlinearConstraint(cons_f,
                                   min_scaling_aspect_val,
                                   max_scaling_aspect_val,
                                   jac=jacobian,
                                   hess=hessian)
Ejemplo n.º 8
0
    def add_objective(self, poly=None, custom=None, maximise=False):
        """
        Adds objective function to be optimised.

        :param poly poly:
            A Poly object.
        :param dict custom: Optional arguments centered around the custom option.
            :callable function: The objective function to be called.
            :callable jac_function: The gradient (or derivative) of the objective.
            :callable hess_function: The Hessian of the objective function.
        :param bool maximise: A flag to specify if the user would like to maximise the function instead of minimising it.
        """
        assert poly is not None or custom is not None
        if self.method == 'trust-region':
            assert poly is None
            assert custom is not None
        self.maximise = maximise
        k = 1.0
        if self.maximise:
            k = -1.0
        if poly is not None:
            f = poly.get_polyfit_function()
            jac = poly.get_polyfit_grad_function()
            hess = poly.get_polyfit_hess_function()
            objective = lambda x: k * np.asscalar(f(x))
            objective_deriv = lambda x: k * jac(x)[:, 0]
            objective_hess = lambda x: k * hess(x)[:, :, 0]
        elif custom is not None:
            assert 'function' in custom
            objective = lambda s: k * custom['function'](s)
            if 'jac_function' in custom:
                objective_deriv = lambda s: k * custom['jac_function'](s)
            else:
                objective_deriv = '2-point'
            if 'hess_function' in custom:
                objective_hess = lambda s: k * custom['hess_function'](s)
            else:
                objective_hess = optimize.BFGS()
        self.objective = {
            'function': objective,
            'gradient': objective_deriv,
            'hessian': objective_hess
        }
Ejemplo n.º 9
0
    def __init__(self,
                 game,
                 dist_measures=None,
                 dist_tensor=None,
                 epsilon=1e-4):
        """
        Parameters
        ----------

        dist_measures: A list of integers with the distortions from
        self.dist_tensor to be considered
        """
        RDT.__init__(self, game, dist_tensor, epsilon)
        self.states = len(self.pmf)
        if dist_measures:
            self.dist_measures = dist_measures
        else:
            self.dist_measures = range(self.dist_tensor.shape[0])
        self.hess = opt.BFGS(exception_strategy='skip_update')
        self.bounds = opt.Bounds(0, 1)
        self.constraint = self.lin_constraint(self.dist_measures)
        self.default_cond_init = self.cond_init()
Ejemplo n.º 10
0
    def train(self, dataset):
        '''
        doc
        '''
        self.train_times += 1
        state_batch, action_batch, old_log_prob, advantages, ret_batch = self.data_process_MLP(
            dataset)

        # obj_data = self.data_process_MLP_old(dataset)
        # train_batch_ = obj_data
        # train_batch = []
        # for x in train_batch_:
        #     for y in x:
        #         train_batch.append(y)

        # state_batch_old = np.array([x[0] for x in train_batch])
        # action_batch_old = np.array([x[1] for x in train_batch])
        # old_log_prob_old = np.array([x[2] for x in train_batch])
        # advantages_old = np.array([x[3] for x in train_batch]) ###### note shape
        # ret_old = np.array([x[4] for x in train_batch])
        # # print('ret_old shape is: ', ret_old.shape)
        # Return = torch.tensor([x[4] for x in train_batch], dtype = torch.float, device = self.device).unsqueeze(1)

        # print('state diff: ', np.sum(np.abs(state_batch - state_batch_old)))
        # print('action diff: ', np.sum(np.abs(action_batch - action_batch_old)))
        # print('old log prob diff: ', np.sum(np.abs(old_log_prob - old_log_prob_old)))
        # print('return diff: ', np.sum(np.abs(ret_batch - ret_old)))
        # exit()

        def ppo_obj(w, w1_num, state_dim, sigma, w1_shape, w2_shape, s_batch,
                    a_batch, prev_log_prob_batch, adv_batch, eps, device):
            w1 = w[:w1_num]
            w2 = w[w1_num:]

            w1 = w1.reshape(w1_shape, order='F')
            w2 = w2.reshape(w2_shape, order='F')

            left_s_batch = s_batch[:, :state_dim]
            right_s_batch = s_batch[:, 1:]
            left_a_batch = a_batch[:, 0].reshape(-1, 1)
            right_a_batch = a_batch[:, 1].reshape(-1, 1)

            left_mean_batch = np.dot(0.5 * (np.dot(left_s_batch, w1))**2, w2)
            right_mean_batch = np.dot(0.5 * (np.dot(right_s_batch, w1))**2, w2)
            left_new_log_prob_batch = -0.5 * np.log(2 * np.pi) - 0.5 * (
                left_a_batch - left_mean_batch)**2 / sigma**2 - np.log(sigma)
            right_new_log_prob_batch = -0.5 * np.log(2 * np.pi) - 0.5 * (
                right_a_batch - right_mean_batch)**2 / sigma**2 - np.log(sigma)
            new_log_prob_batch = left_new_log_prob_batch + right_new_log_prob_batch

            ratio = np.exp(new_log_prob_batch - prev_log_prob_batch)
            obj1 = ratio * adv_batch
            obj2 = np.clip(ratio, 1 - eps, 1 + eps) * adv_batch
            ppo_obj = -np.mean(np.minimum(obj1, obj2))

            return ppo_obj

        def ppo_obj_grad(w, w1_num, state_dim, sigma, w1_shape, w2_shape,
                         s_batch, a_batch, prev_log_prob_batch, adv_batch, eps,
                         device):
            ori_len = len(w)
            assert w1_num == w1_shape[0] * w1_shape[1]
            assert ori_len == w1_num + w2_shape[0] * w2_shape[1]
            w1 = w[:w1_num]
            w2 = w[w1_num:]

            w1 = w1.reshape(w1_shape, order='F')
            w2 = w2.reshape(w2_shape, order='F')
            w1 = torch.tensor(w1,
                              dtype=torch.float,
                              requires_grad=True,
                              device=device)
            w2 = torch.tensor(w2,
                              dtype=torch.float,
                              requires_grad=True,
                              device=device)

            left_s_batch = s_batch[:, :state_dim]
            right_s_batch = s_batch[:, 1:]
            left_a_batch = a_batch[:, 0].reshape(-1, 1)
            right_a_batch = a_batch[:, 1].reshape(-1, 1)

            left_s_batch = torch.tensor(left_s_batch,
                                        dtype=torch.float,
                                        device=device)
            right_s_batch = torch.tensor(right_s_batch,
                                         dtype=torch.float,
                                         device=device)
            left_a_batch = torch.tensor(left_a_batch,
                                        dtype=torch.float,
                                        device=device)
            right_a_batch = torch.tensor(right_a_batch,
                                         dtype=torch.float,
                                         device=device)
            prev_log_prob_batch = torch.tensor(prev_log_prob_batch,
                                               dtype=torch.float,
                                               device=device)
            adv_batch = torch.tensor(adv_batch,
                                     dtype=torch.float,
                                     device=device)

            sigma_tensor = torch.tensor(sigma,
                                        dtype=torch.float,
                                        device=device)
            pi_tensor = torch.tensor(-0.5 * np.log(2 * np.pi),
                                     dtype=torch.float,
                                     device=device)
            left_mean_batch = torch.mm(0.5 * (torch.mm(left_s_batch, w1))**2,
                                       w2)
            right_mean_batch = torch.mm(0.5 * (torch.mm(right_s_batch, w1))**2,
                                        w2)
            left_new_log_prob_batch = pi_tensor - 0.5 * (
                left_a_batch - left_mean_batch)**2 / (
                    sigma_tensor**2) - torch.log(sigma_tensor)
            right_new_log_prob_batch = pi_tensor - 0.5 * (
                right_a_batch - right_mean_batch)**2 / (
                    sigma_tensor**2) - torch.log(sigma_tensor)
            new_log_prob_batch = left_new_log_prob_batch + right_new_log_prob_batch

            ratio = torch.exp(new_log_prob_batch - prev_log_prob_batch)
            obj1 = ratio * adv_batch
            obj2 = torch.clamp(ratio, 1 - eps, 1 + eps) * adv_batch
            ppo_obj = -torch.min(obj1, obj2).mean()

            ppo_obj.backward()
            with torch.no_grad():
                w1_grad = w1.grad.cpu().numpy()
                w2_grad = w2.grad.cpu().numpy()
            w1_grad = w1_grad.reshape((-1, ), order='F')
            w2_grad = w2_grad.reshape((-1, ), order='F')
            grad = np.concatenate((w1_grad, w2_grad))
            assert len(grad) == ori_len
            return grad

        if self.train_times > self.args.value_pre_train_time:
            w1_ = self.w1.reshape((-1, ), order='F')
            w2_ = self.w2.reshape((-1, ), order='F')
            w0 = np.concatenate((w1_, w2_))
            # w, w1_num, w1_shape, w2_shape, s_batch, a_batch, prev_log_prob_batch, adv_batch, eps
            #  w, w1_num, state_dim, sigma, w1_shape, w2_shape, s_batch, a_batch, prev_log_prob_batch, adv_batch, eps, device):
            res = soptim.minimize(
                ppo_obj,
                w0,
                method='trust-constr',
                jac=ppo_obj_grad,
                hess=soptim.BFGS(),
                constraints=[self.linear_constraint],
                args=(self.w1_num, self.state_dim, self.sigma, self.w1_shape,
                      self.w2_shape, state_batch, action_batch, old_log_prob,
                      advantages, self.eps, self.device),
                options={'verbose': self.args.scipy_verbose})

            new_w = res.x
            self.w1 = new_w[:self.w1_num]
            self.w2 = new_w[self.w1_num:]
            self.w1 = self.w1.reshape(self.w1_shape, order='F')
            self.w2 = self.w2.reshape(self.w2_shape, order='F')

        # tb_value_loss = 0
        # value_states_old = self.expand_value_state(state_batch_old)
        # state_batch_tensor = torch.tensor(value_states_old, dtype = torch.float, device = self.device)
        # for i in range(self.args.constrained_ppo_value_train_iter):
        #     state_values = self.value_net(state_batch_tensor)
        #     closs = (Return - state_values) ** 2
        #     closs = closs.mean()
        #     tb_value_loss += closs.detach().cpu().item()
        #     self.c_optimizer.zero_grad()
        #     closs.backward()
        #     self.c_optimizer.step()

        # tb_value_loss /= self.args.constrained_ppo_value_train_iter
        # if self.tb_writter is not None:
        #     self.tb_writter.add_scalar('value_loss', tb_value_loss, self.train_times)

        constraint_violence = self.check_constraint()
        if self.tb_writter is not None:
            self.tb_writter.add_scalar('constraint_violence',
                                       constraint_violence, self.train_times)
Ejemplo n.º 11
0
    def add_nonlinear_ineq_con(self, poly=None, custom=None):
        """
        Adds nonlinear inequality constraints :math:`lb <= g(x) <= ub` (for poly option) with :math:`lb`, :math:`ub = bounds` or :math:`g(x) >= 0` (for function option) to the optimisation problem. Only ``trust-constr``, ``COBYLA``, and ``SLSQP`` methods can handle general constraints.
        If Poly object is provided in the poly dictionary, gradients and Hessians will be computed automatically. If a lambda function is provided in the ``function`` dictionary, the user may also provide ``jac_function`` for gradients and ``hess_function`` for Hessians; otherwise, a 2-point differentiation rule
        will be used to approximate the derivative and a BFGS update will be used to approximate the Hessian.

        :param dict poly: Arguments for poly dictionary.
            :param Poly poly: An instance of the Poly class.
            :param numpy.ndarray bounds: An array with two entries specifying the lower and upper bounds of the inequality. If there is no lower bound, set bounds[0] = -np.inf.If there is no upper bound, set bounds[1] = np.inf.
        :param dict custom: Additional custom callable arguments.
            :callable function: The constraint function to be called.
            :callable jac_function: The gradient (or derivative) of the constraint.
            :callable hess_function: The Hessian of the constraint function.
        """
        assert self.method in ['SLSQP', 'trust-constr', 'COBYLA']
        assert poly is not None or custom is not None
        if poly is not None:
            assert 'bounds' in poly
            bounds = poly['bounds']
            assert 'poly' in poly
            gpoly = poly['poly']
            # Get lambda functions for function, gradient, and Hessians from poly object
            g = gpoly.get_polyfit_function()
            jac = gpoly.get_polyfit_grad_function()
            hess = gpoly.get_polyfit_hess_function()
            constraint = lambda x: g(x)[0]
            constraint_deriv = lambda x: jac(x)[:, 0]
            constraint_hess = lambda x, v: hess(x)[:, :, 0]
            if self.method == 'trust-constr':
                self.constraints.append(
                    optimize.NonlinearConstraint(constraint,
                                                 bounds[0],
                                                 bounds[1],
                                                 jac=constraint_deriv,
                                                 hess=constraint_hess))
            # other methods add inequality constraints using dictionary files
            elif self.method == 'SLSQP':
                if not np.isinf(bounds[0]):
                    self.constraints.append({
                        'type':
                        'ineq',
                        'fun':
                        lambda x: constraint(x) - bounds[0],
                        'jac':
                        constraint_deriv
                    })
                if not np.isinf(bounds[1]):
                    self.constraints.append({
                        'type':
                        'ineq',
                        'fun':
                        lambda x: -constraint(x) + bounds[1],
                        'jac':
                        lambda x: -constraint_deriv(x)
                    })
            else:
                if not np.isinf(bounds[0]):
                    self.constraints.append({
                        'type':
                        'ineq',
                        'fun':
                        lambda x: constraint(x) - bounds[0]
                    })
                if not np.isinf(bounds[1]):
                    self.constraints.append({
                        'type':
                        'ineq',
                        'fun':
                        lambda x: -constraint(x) + bounds[1]
                    })
        elif custom is not None:
            assert 'function' in custom
            constraint = custom['function']
            if 'jac_function' in custom:
                constraint_deriv = custom['jac_function']
            else:
                constraint_deriv = '2-point'
            if 'hess_function' in custom:
                constraint_hess = lambda x, v: custom['hess_function'](x)
            else:
                constraint_hess = optimize.BFGS()
            if self.method == 'trust-constr':
                self.constraints.append(
                    optimize.NonlinearConstraint(constraint,
                                                 0.0,
                                                 np.inf,
                                                 jac=constraint_deriv,
                                                 hess=constraint_hess))
            elif self.method == 'SLSQP':
                if 'jac_function' in custom:
                    self.constraints.append({
                        'type': 'ineq',
                        'fun': constraint,
                        'jac': constraint_deriv
                    })
                else:
                    self.constraints.append({
                        'type': 'ineq',
                        'fun': constraint
                    })
            else:
                self.constraints.append({'type': 'ineq', 'fun': constraint})
Ejemplo n.º 12
0
# # FA ~ 0.2425
# ratio_min = 1.5

# FA ~ 0.0
ratio_min = 1.

# FA ~ 0.8111
ratio_max = 6.0
#################################################

## nonlinear ratio constraint object
fa_cons = opt.NonlinearConstraint(ratio,
                                  np.array([ratio_min]),
                                  np.array([ratio_max]),
                                  jac=ratio_jac,
                                  hess=opt.BFGS())


## uFA for this type of models
def microFA(d1, d2, d3, fin, fex, fcsf):
    # if (fin < 0) or (fex < 0) or (fin + fex > 1):
    # 	return np.nan

    microAx = fin * d1 + fex * d2 + fcsf * 3
    microRad = fex * d3 + fcsf * 3
    microMean = (microAx + 2 * microRad) / 3.
    microFA = np.sqrt(
        (3 / 2.) * ((microAx - microMean)**2 + 2 * (microRad - microMean)**2) /
        (microAx**2 + 2 * microRad**2))
    return microFA
Ejemplo n.º 13
0
N = 50
delta = np.linspace(0.001, 0.75, N)

#Create empty array for solutions
q_optimal = np.array([])
cmu_optimal = np.array([])

#Find solutions for every delta
for i in range(N):
    R = delta[i] * 2
    while np.abs(R - delta[i]) > 1E-4:
        print(R, delta[i])
        x0 = initialize_x(1, init_type='normal')  #Must be length of one

        nonlinear_constraint = optimize.NonlinearConstraint(
            cons_c, lb=0.0, ub=delta[i], jac='3-point', hess=optimize.BFGS())
        res = optimize.minimize(cmu_Q,
                                x0,
                                method='trust-constr',
                                constraints=[nonlinear_constraint],
                                tol=1E-12,
                                options={
                                    'verbose': 1,
                                    'xtol': 1E-12,
                                    'gtol': 1E-12,
                                    'maxiter': 2500
                                },
                                bounds=bounds)
        q = np.asarray(np.real(res.x))
        R = cons_c(q)
Ejemplo n.º 14
0
 def optimize( self ):
     res = so.minimize( self.loss, self.w, constraints=self.constraints, jac='2-point', hess=so.BFGS(), method='trust-constr', options={'verbose':1,'maxiter':1024,'xtol':1e-8} )
     self.w = res.x