def test_temperature_update(self):
        """Test if temperature updates affect gradients."""
        flow = flows.DiscreteFlow(self.N, self.K, 
                temperature=10., layers=[("M",[256, 256]), ("F", None), ("M",[])]) 

        with tf.GradientTape() as tape:
            loss = -tf.reduce_sum(forward(flow, self.base_samples))
        g1 = tape.gradient(loss, flow.trainable_variables)

        with tf.GradientTape() as tape:
            flow.temperature = 1.0
            loss = -tf.reduce_sum(forward(flow, self.base_samples))
        g2 = tape.gradient(loss, flow.trainable_variables)

        with tf.GradientTape() as tape:
            flow.temperature = 0.1
            loss = -tf.reduce_sum(forward(flow, self.base_samples))
        g3 = tape.gradient(loss, flow.trainable_variables)

        difference_g1g2 = sum( np.sum(abs(e1-e2)) for e1, e2 in zip(g1,g2) )
        difference_g1g3 = sum( np.sum(abs(e1-e2)) for e1, e2 in zip(g1,g3) )

        logger.debug("Total gradient difference for temperature 10 vs 1: %s" % difference_g1g2)
        logger.debug("Total gradient difference for temperature 10 vs 0.1: %s" % difference_g1g3)

        self.assertNotEqual(difference_g1g2, 0.0)
        self.assertNotEqual(difference_g1g3, 0.0)
        self.assertNotEqual(difference_g1g3, difference_g1g2)
    def test_discrete_flows_different_inputs(self):
        """Tests various flows by passing two different inputs and checking if outputs differ."""
        N = self.N
        for i, layers in enumerate(self.layers_specs):
            logger.debug("#"*30+" [%i/%i] testing repeated samples (reverse) %s" % \
                          (i+1, len(self.layers_specs), layers))
            flow = flows.DiscreteFlow(self.N, self.K, temperature=5.0, layers=copy.deepcopy(layers))

            out = flow(self.equal_samples[0:1])         
            out2 = flow(self.equal_samples2[0:1])         
            self.assertTrue(out.shape==out2.shape)
                        
            self.assertTrue( sum(bool(tf.reduce_any(out[0,n]!=out2[0,n])) for n in range(self.N))>0, \
                             "at least one dim in outputs must differ" )
    def test_discrete_flows_deterministic_reverse(self):
        """Tests various flows by passing set of exactly the same samples and checking if result is the same."""
        N = self.N
        for i, layers in enumerate(self.layers_specs):
            logger.debug("#"*30+" [%i/%i] testing repeated samples (reverse) %s" % \
                          (i+1, len(self.layers_specs), layers))
            flow = flows.DiscreteFlow(self.N, self.K, temperature=5.0, layers=copy.deepcopy(layers))

            out = flow.reverse(self.equal_samples)         
            self.assertTrue( sum([bool(tf.reduce_all(out[n] == out[n+1])) for n in range(N-1)])==N-1, 
                             "all samples the same")

            out = flow.reverse(self.equal_samples2)         
            self.assertTrue( sum([bool(tf.reduce_all(out[n] == out[n+1])) for n in range(N-1)])==N-1, 
                             "all samples the same")
 def test_discrete_flows_invertability(self):
     """Tests various flows by passing samples both directions and checking if input is recovered."""
     for i, layers in enumerate(self.layers_specs):
         logger.debug("#"*30+" [%i/%i] testing invertability of %s" % (i+1, len(self.layers_specs), layers))
         flow = flows.DiscreteFlow(self.N, self.K, temperature=5.0, layers=copy.deepcopy(layers))
         self.assert_forward_reverse(flow, str(layers))