def testNearZeroObjectivesAndDirectionCoordinates(self):
        multi_objectives = tf.constant([[3, 0, 0]], dtype=tf.float32)

        # direction with small non-zero coordinates.
        nonzero = 2 * multi_objective_scalarizer.HyperVolumeScalarizer.ALMOST_ZERO
        direction = [1, nonzero, nonzero]
        scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            direction, self._hv_params)
        self.assertAllClose(self.evaluate(scalarizer(multi_objectives)),
                            self.evaluate(tf.constant([0], dtype=tf.float32)))

        # direction with coordinates that are so small in magnitude that would be
        # considered zeros.
        direction = [1, 1e-30, 1e-30]
        scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            direction, self._hv_params)
        self.assertAllClose(self.evaluate(scalarizer(multi_objectives)),
                            self.evaluate(tf.constant([3], dtype=tf.float32)))

        # direction with absolute zero coordinates.
        direction = [1, 0, 0]
        scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            direction, self._hv_params)
        self.assertAllClose(self.evaluate(scalarizer(multi_objectives)),
                            self.evaluate(tf.constant([3], dtype=tf.float32)))
    def testCustomTransform(self):
        transform = lambda m, s, o: m * s + o
        scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            [1, 0, 0], self._hv_params, transform)
        self.assertAllClose(
            self.evaluate(scalarizer(self._batch_multi_objectives)),
            self.evaluate(tf.constant([3, 6], dtype=tf.float32)))

        transform2 = lambda m, s, o: tf.multiply(m, m) * s + o
        scalarizer2 = multi_objective_scalarizer.HyperVolumeScalarizer(
            [0.1, 0.2, 0.2], self._hv_params, transform2)
        self.assertAllClose(
            self.evaluate(scalarizer2(self._batch_multi_objectives)),
            self.evaluate(tf.constant([1.5, 24.], dtype=tf.float32)))
 def testAxisAlignedDirection(self):
     direction = [0, 1, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, self._hv_params)
     self.assertAllEqual(
         self.evaluate(scalarizer(self._batch_multi_objectives)),
         self.evaluate(tf.constant([2, 5], dtype=tf.float32)))
 def testDirectionNormalization(self):
     for direction in [[1, 2, 2], [0.1, 0.2, 0.2]]:
         scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
             direction, self._hv_params)
         self.assertAllClose(
             self.evaluate(scalarizer(self._batch_multi_objectives)),
             self.evaluate(tf.constant([1.5, 6], dtype=tf.float32)))
 def testNegativeObjectives(self):
     direction = [1, 0, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, self._hv_params)
     self.assertAllEqual(
         self.evaluate(scalarizer(-1.0 * self._batch_multi_objectives)),
         self.evaluate(tf.constant([0, 0], dtype=tf.float32)))
 def setUp(self):
     super(ScalarizeObjectivesTest, self).setUp()
     hv_params = [
         multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS(slope=1,
                                                                 offset=0)
     ] * 3
     self._scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         [0, 1, 0.01], hv_params)
 def testInvalidObjectives(self):
     with self.assertRaisesRegex(
             ValueError, 'The number of input objectives should be'):
         direction = [1, 0, 0]
         scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
             direction, self._hv_params)
         multi_objectives = tf.constant([[1, 2, 3, 4]], dtype=tf.float32)
         scalarizer(multi_objectives)
 def testCallDirectionWrongBatchSizeRaisesValueError(self):
     direction = [1, 0, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, self._hv_params)
     with self.assertRaisesRegex(ValueError, 'does not match the shape of'):
         scalarizer.set_parameters(direction=tf.constant(
             [[0, 1, 0], [1, 0, 0], [0, 0, 1]], dtype=tf.float32),
                                   transform_params={})
         self.evaluate(scalarizer(self._batch_multi_objectives))
 def testNegativeObjectives(self):
     direction = [1, 0, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, self._hv_params)
     multi_objectives = tf.constant([[-3, 2, 1], [-6, 5, 4]],
                                    dtype=tf.float32)
     self.assertAllEqual(
         self.evaluate(scalarizer(multi_objectives)),
         self.evaluate(tf.constant([0, 0], dtype=tf.float32)))
 def testSetParametersDirectionOnly(self):
     direction = [1, 0, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, self._hv_params)
     scalarizer.set_parameters(direction=tf.constant([[0, 1, 0], [0, 0, 1]],
                                                     dtype=tf.float32),
                               transform_params={})
     self.assertAllClose(
         self.evaluate(scalarizer(self._batch_multi_objectives)),
         self.evaluate(tf.constant([2, 4], dtype=tf.float32)))
 def testObjectiveTranformation(self):
     hv_params = copy.deepcopy(self._hv_params)
     hv_params[0] = multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS(
         slope=-1, offset=2)
     direction = [1, 0, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, hv_params)
     self.assertAllEqual(
         self.evaluate(scalarizer(-1.0 * self._batch_multi_objectives)),
         self.evaluate(tf.constant([5, 8], dtype=tf.float32)))
 def testSetParametersDirectionWithWrongNumberOfObjectivesRaisesValueError(
     self):
   direction = [1, 0, 0]
   scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
       direction, self._hv_params)
   with self.assertRaisesRegex(
       ValueError, 'The number of objectives in scalarization parameter'):
     scalarizer.set_parameters(
         direction=tf.constant([[0, 1]] * 2, dtype=tf.float32),
         transform_params={})
 def testSetParametersInvalidTransformationParamsKeysRaisesValueError(self):
   direction = [1, 0, 0]
   scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
       direction, self._hv_params)
   with self.assertRaisesRegex(ValueError,
                               'All transform_params keys should be'):
     scalarizer.set_parameters(
         direction=tf.constant([[0, 1, 0], [0, 0, 1]], dtype=tf.float32),
         transform_params={
             'weights': tf.constant([1, 1, 1], dtype=tf.float32)
         })
 def testSetParametersDirectionAndOffset(self):
     direction = [1, 0, 0]
     scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         direction, self._hv_params)
     scalarizer.set_parameters(
         direction=tf.constant([[0, 1, 0], [0, 0, 1]], dtype=tf.float32),
         transform_params={
             multi_objective_scalarizer.HyperVolumeScalarizer.OFFSET_KEY:
             tf.constant([[0.5, 0.5, 0.5], [0.1, 0.1, 0.1]],
                         dtype=tf.float32)
         })
     self.assertAllClose(
         self.evaluate(scalarizer(self._batch_multi_objectives)),
         self.evaluate(tf.constant([2.5, 4.1], dtype=tf.float32)))
 def setUp(self):
     super(GreedyRewardPredictionPolicyTest, self).setUp()
     self._obs_spec = tensor_spec.TensorSpec([2], tf.float32)
     self._time_step_spec = ts.time_step_spec(self._obs_spec)
     self._action_spec = tensor_spec.BoundedTensorSpec((), tf.int32, 0, 2)
     hv_params = [
         multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS(slope=1,
                                                                 offset=0)
     ] * 3
     self._scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
         [0, 1, 0.01], hv_params)
     self._bias = np.asarray([-1, -1, -1])
     self._kernel_weights = [
         np.asarray([[1, 2, 3], [4, 5, 6]]),
         np.asarray([[3, 1, 2], [5, 4, 6]]),
         np.asarray([[2, 3, 1], [5, 6, 4]])
     ]
 def setUp(self):
   super(MultiObjectiveAgentTest, self).setUp()
   tf.compat.v1.enable_resource_variables()
   self._time_step_spec = ts.time_step_spec(
       observation_spec=tensor_spec.TensorSpec([2], tf.float32),
       reward_spec=tensor_spec.TensorSpec([3], tf.float32))
   self._action_spec = tensor_spec.BoundedTensorSpec(
       dtype=tf.int32, shape=(), minimum=0, maximum=2)
   self._observation_spec = self._time_step_spec.observation
   hv_params = [
       multi_objective_scalarizer.HyperVolumeScalarizer.PARAMS(
           slope=1, offset=0)
   ] * 3
   self._scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
       [0, 1, 0.01], hv_params)
   self._bias = np.asarray([-1, -1, -1])
   self._kernel_weights = [
       np.asarray([[1, 2, 3], [4, 5, 6]]),
       np.asarray([[3, 1, 2], [5, 4, 6]]),
       np.asarray([[2, 3, 1], [5, 6, 4]])
   ]
    def testCustomTransform(self):
        transform = lambda m, s, o: m * s + o
        scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            [1, 0, 0], self._hv_params, transform)
        self.assertAllClose(scalarizer(self._batch_multi_objectives), [3, 6])

        transform2 = lambda m, s, o: tf.multiply(m, m) * s + o
        scalarizer2 = multi_objective_scalarizer.HyperVolumeScalarizer(
            [0.1, 0.2, 0.2], self._hv_params, transform2)
        self.assertAllClose(scalarizer2(self._batch_multi_objectives),
                            [1.5, 24.])

        def default_transform(metrics, slopes, offsets):
            transformed_metrics = metrics
            return transformed_metrics * slopes + offsets

        scalarizer3 = multi_objective_scalarizer.HyperVolumeScalarizer(
            [0.1, 0.2, 0.2], self._hv_params, default_transform)
        default_scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            [0.1, 0.2, 0.2], self._hv_params)
        self.assertAllClose(
            self.evaluate(scalarizer3(self._batch_multi_objectives)),
            self.evaluate(default_scalarizer(self._batch_multi_objectives)))

        # Apply sigmoid to the 2nd metric.
        sigmoid_metric_mask = [False, True, False]
        batch_size = self._batch_multi_objectives.shape[0]
        sigmoid_batch_mask = tf.reshape(
            tf.tile(sigmoid_metric_mask, [batch_size]),
            [batch_size, len(sigmoid_metric_mask)])

        def sigmoid_metric_transform(metrics: tf.Tensor, slopes, offsets):
            transformed_values = tf.where(sigmoid_batch_mask,
                                          tf.sigmoid(metrics), metrics)
            return transformed_values * slopes + offsets

        sigmoid_scalarizer = multi_objective_scalarizer.HyperVolumeScalarizer(
            [0.1, 0.2, 0.2], self._hv_params, sigmoid_metric_transform)

        self.assertAllClose(sigmoid_scalarizer(self._batch_multi_objectives),
                            [1.321196, 1.489961])

        sigmoid_scalarizer2 = multi_objective_scalarizer.HyperVolumeScalarizer(
            [0, 1.0, 0], self._hv_params, sigmoid_metric_transform)
        self.assertAllClose(sigmoid_scalarizer2(self._batch_multi_objectives),
                            [0.880797, 0.993307])
 def testZeroLengthDirection(self):
     with self.assertRaisesRegex(ValueError, 'nearly-zero vector'):
         direction = [0, 0, 0]
         multi_objective_scalarizer.HyperVolumeScalarizer(
             direction, self._hv_params)
 def testDirectionWithWrongDimension(self):
     with self.assertRaisesRegex(ValueError,
                                 'direction has 2 elements but'):
         direction = [1, 0]
         multi_objective_scalarizer.HyperVolumeScalarizer(
             direction, self._hv_params)
 def testInvalidParams(self):
     with self.assertRaisesRegex(ValueError, 'nearly-zero vector'):
         multi_objective_scalarizer.HyperVolumeScalarizer([], [])
     with self.assertRaisesRegex(ValueError, 'at least two objectives'):
         multi_objective_scalarizer.HyperVolumeScalarizer(
             [1], [self._hv_params[0]])
 def testDirectionWithNegativeCoordinates(self):
     with self.assertRaisesRegex(ValueError, 'has negative coordinates'):
         direction = [-1, 0, 0]
         multi_objective_scalarizer.HyperVolumeScalarizer(
             direction, self._hv_params)