(self, action_space, constraint=None)
Optimize the policy for a given value function.

        Parameters
        ----------
        action_space : ndarray
            The parameter value to evaluate (for each parameter). This is
            geared towards piecewise linear functions.
        constraint : callable
            A function that can be called with a policy. Returns the slack of
            the safety constraint for each state. A policy is safe if the slack
            is >=0 for all constraints.
Optimize the policy for a given value function.
Optimize the policy for a given value function .
def discrete_policy_optimization(self, action_space, constraint=None):
        """Optimize the policy for a given value function.

        Parameters
        ----------
        action_space : ndarray
            The parameter value to evaluate (for each parameter). This is
            geared towards piecewise linear functions.
        constraint : callable
            A function that can be called with a policy. Returns the slack of
            the safety constraint for each state. A policy is safe if the slack
            is >=0 for all constraints.
        """
        states = self.policy.discretization.all_points
        n_states = states.shape[0]
        n_options, n_actions = action_space.shape

        # Initialize
        values = np.empty((n_states, n_options), dtype=config.np_dtype)
        action_array = np.broadcast_to(np.zeros(n_actions,
                                                dtype=config.np_dtype),
                                       (n_states, n_actions))

        # Create tensorflow operations, but reuse previous graph elements
        storage = get_storage(self._storage)

        if storage is None:
            # Computation of future values
            actions = tf.placeholder(config.dtype,
                                     shape=action_array.shape,
                                     name='actions')
            future_values = self.future_values(states,
                                               actions=actions)

            # Assigning new parameters
            parameters = tf.placeholder(config.dtype, action_array.shape)
            assign_op = tf.assign(self.policy.parameters[0], parameters)

            # Put things into storage
            storage = [('actions', actions),
                       ('future_values', future_values),
                       ('parameters', parameters),
                       ('assign_op', assign_op)]
            set_storage(self._storage, storage)
        else:
            # Get items out of storage
            actions, future_values, parameters, assign_op = storage.values()

        feed_dict = self.feed_dict
        feed_dict[actions] = action_array

        # Compute values for each action
        for i, action in enumerate(action_space):
            # Update feed dict
            action_array.base[:] = action
            # Compute values
            values[:, i] = future_values.eval(feed_dict=feed_dict)[:, 0]

            if constraint is not None:
                # TODO: optimize safety if unsafe
                unsafe = constraint(action_array) < 0
                values[unsafe, i] = -np.inf

        # Select best action for policy
        best_actions = action_space[np.argmax(values, axis=1)]
        assign_op.eval({parameters: best_actions})
def discrete_policy_optimization ( self , action_space , constraint = None ) : states = self . policy . discretization . all_points n_states = states . shape [ 0 ] n_options , n_actions = action_space . shape # Initialize values = np . empty ( ( n_states , n_options ) , dtype = config . np_dtype ) action_array = np . broadcast_to ( np . zeros ( n_actions , dtype = config . np_dtype ) , ( n_states , n_actions ) ) # Create tensorflow operations, but reuse previous graph elements storage = get_storage ( self . _storage ) if storage is None : # Computation of future values actions = tf . placeholder ( config . dtype , shape = action_array . shape , name = 'actions' ) future_values = self . future_values ( states , actions = actions ) # Assigning new parameters parameters = tf . placeholder ( config . dtype , action_array . shape ) assign_op = tf . assign ( self . policy . parameters [ 0 ] , parameters ) # Put things into storage storage = [ ( 'actions' , actions ) , ( 'future_values' , future_values ) , ( 'parameters' , parameters ) , ( 'assign_op' , assign_op ) ] set_storage ( self . _storage , storage ) else : # Get items out of storage actions , future_values , parameters , assign_op = storage . values ( ) feed_dict = self . feed_dict feed_dict [ actions ] = action_array # Compute values for each action for i , action in enumerate ( action_space ) : # Update feed dict action_array . base [ : ] = action # Compute values values [ : , i ] = future_values . eval ( feed_dict = feed_dict ) [ : , 0 ] if constraint is not None : # TODO: optimize safety if unsafe unsafe = constraint ( action_array ) < 0 values [ unsafe , i ] = - np . inf # Select best action for policy best_actions = action_space [ np . argmax ( values , axis = 1 ) ] assign_op . eval ( { parameters : best_actions } )