def test_four(self):
        """
        All equal duty cycle, boost factor 0, k = 0,1, and n, batch size 1.
        """

        # Setup input.
        x = self.x4
        duty_cycles = self.duty_cycles4

        # Test forward with boost factor of 1 and k=0.
        expected = np.zeros(x.shape, dtype=np.float32)

        result = compute_kwinners(x, 0, duty_cycles, boost_strength=1.0)
        self.assertAllEqual(result, expected)

        # Test forward with boost factor of 1 and k=1.
        expected[0, -1] = x[0, -1]

        result = compute_kwinners(x, 1, duty_cycles, boost_strength=1.0)
        self.assertAllEqual(result, expected)

        # Test forward with boost factor of 1 and k=1.
        expected = np.copy(x)

        result = compute_kwinners(x, 10, duty_cycles, boost_strength=1.0)
        self.assertAllEqual(result, expected)
    def test_three(self):
        """
        Unequal duty cycle, boost factor 0 (and then over a range), k = 3, batch size 2.
        """

        # Setup input.
        x = self.x3
        duty_cycles = self.duty_cycles3

        # Test forward with boost factor of 0.
        expected = np.zeros(x.shape, dtype=np.float32)
        expected[0, 2] = x[0, 2]
        expected[0, 3] = x[0, 3]
        expected[1, 1] = x[1, 1]
        expected[1, 5] = x[1, 5]

        result = compute_kwinners(x, 2, duty_cycles, boost_strength=0.0)
        self.assertAllEqual(result, expected)

        # Test forward again with boost factor from 1 to 10. Should yield the same
        # result as the negative numbers will never be in the top k and the non-one
        # values have very large duty cycles.
        expected = np.zeros(x.shape, dtype=np.float32)
        expected[0, 3] = x[0, 3]
        expected[0, 5] = x[0, 5]
        expected[1, 1] = x[1, 1]
        expected[1, 5] = x[1, 5]

        for b in np.arange(2.0, 10.0, dtype=np.float32):
            result = compute_kwinners(x, 2, duty_cycles, boost_strength=b)
            self.assertAllEqual(result, expected)
    def test_tie_breaking(self):
        """
        Test k-winners with tie-breaking
        """
        x = self.x2
        # Force tie breaking
        x[0, 5] = x[0, 1]

        # Expected with [0, 1] winning the tie-break
        expected1 = np.zeros_like(x)
        expected1[0, 0] = x[0, 0]
        expected1[0, 1] = x[0, 1]
        expected1[0, 3] = x[0, 3]
        expected1[1, 1] = x[1, 1]
        expected1[1, 3] = x[1, 3]
        expected1[1, 5] = x[1, 5]

        # Expected with [0, 5] winning the tie-break
        expected2 = np.zeros_like(x)
        expected2[0, 0] = x[0, 0]
        expected2[0, 3] = x[0, 3]
        expected2[0, 5] = x[0, 5]
        expected2[1, 1] = x[1, 1]
        expected2[1, 3] = x[1, 3]
        expected2[1, 5] = x[1, 5]
        result = compute_kwinners(x,
                                  k=3,
                                  duty_cycles=self.duty_cycles2,
                                  boost_strength=1.0)
        result = keras.backend.get_value(result)
        self.assertTrue(
            np.array_equal(result, expected1)
            or np.array_equal(result, expected2))
    def test_two(self):
        """
        Unequal duty cycle, boost strength 0 to 10, k = 3, batch size 2.
        """

        # Setup input.
        x = self.x2
        duty_cycles = self.duty_cycles2

        # Test forward with boost strength of 0.
        expected = np.zeros(x.shape, dtype=np.float32)
        expected[0, 0] = x[0, 0]
        expected[0, 2] = x[0, 2]
        expected[0, 3] = x[0, 3]
        expected[1, 0] = x[1, 0]
        expected[1, 2] = x[1, 2]
        expected[1, 3] = x[1, 3]

        result = compute_kwinners(x, 3, duty_cycles, boost_strength=0.0)
        self.assertAllEqual(result, expected)

        # Test forward again with boost strength of 1.
        expected = np.zeros(x.shape, dtype=np.float32)
        expected[0, 0] = x[0, 0]
        expected[0, 5] = x[0, 5]
        expected[0, 3] = x[0, 3]
        expected[1, 1] = x[1, 1]
        expected[1, 3] = x[1, 3]
        expected[1, 5] = x[1, 5]

        result = compute_kwinners(x, 3, duty_cycles, boost_strength=1.0)
        self.assertAllEqual(result, expected)

        # Test forward again with boost strength from 2 to 10. Should give save result
        # given the differing duty cycles.
        expected = np.zeros(x.shape, dtype=np.float32)
        expected[0, 1] = x[0, 1]
        expected[0, 3] = x[0, 3]
        expected[0, 5] = x[0, 5]
        expected[1, 1] = x[1, 1]
        expected[1, 3] = x[1, 3]
        expected[1, 5] = x[1, 5]

        for b in np.arange(2.0, 10.0, dtype=np.float32):
            result = compute_kwinners(x, 3, duty_cycles, boost_strength=b)
            self.assertAllEqual(result, expected)
    def test_one(self):
        """boost strength 0 to 10, k=3, batch size 2"""

        # Setup input.
        x = self.x1
        duty_cycles = self.duty_cycles1

        # Test forward pass through the layer.
        expected = np.zeros(x.shape, dtype=np.float32)
        expected[0, 1] = x[0, 1]
        expected[0, 3] = x[0, 3]
        expected[0, 5] = x[0, 5]
        expected[1, 2] = x[1, 2]
        expected[1, 4] = x[1, 4]
        expected[1, 6] = x[1, 6]

        # Loop over floating point boost strengths.
        for b in np.arange(0.0, 10.0, dtype=np.float32):
            # Build layer with varying boost_strength.
            result = compute_kwinners(x, 3, duty_cycles, boost_strength=b)
            self.assertAllEqual(result, expected)