Example #1
0
    def _testLegalInputs(self, shift=None, scale_params=None, x=None):
        def _powerset(x):
            s = list(x)
            return itertools.chain.from_iterable(
                itertools.combinations(s, r) for r in range(len(s) + 1))

        for args in _powerset(scale_params.items()):
            with self.test_session():
                args = dict(args)

                scale_args = dict({"x": x}, **args)
                scale = self._makeScale(**scale_args)

                bijector_args = dict({"event_ndims": 1}, **args)

                # We haven't specified enough information for the scale.
                if scale is None:
                    with self.assertRaisesRegexp(ValueError,
                                                 ("must be specified.")):
                        bijector = affine_lib.Affine(shift=shift,
                                                     **bijector_args)
                else:
                    bijector = affine_lib.Affine(shift=shift, **bijector_args)
                    np_x = x
                    # For the case a vector is passed in, we need to make the shape
                    # match the matrix for matmul to work.
                    if x.ndim == scale.ndim - 1:
                        np_x = np.expand_dims(x, axis=-1)

                    forward = np.matmul(scale, np_x) + shift
                    if x.ndim == scale.ndim - 1:
                        forward = np.squeeze(forward, axis=-1)
                    self.assertAllClose(forward, bijector.forward(x).eval())

                    backward = np.linalg.solve(scale, np_x - shift)
                    if x.ndim == scale.ndim - 1:
                        backward = np.squeeze(backward, axis=-1)
                    self.assertAllClose(backward, bijector.inverse(x).eval())

                    ildj = -np.log(np.abs(np.linalg.det(scale)))
                    # TODO(jvdillon): We need to make it so the scale_identity_multiplier
                    # case does not deviate in expected shape. Fixing this will get rid of
                    # these special cases.
                    if (ildj.ndim > 0 and
                        (len(scale_args) == 1 or
                         (len(scale_args) == 2 and scale_args.get(
                             "scale_identity_multiplier", None) is not None))):
                        ildj = np.squeeze(ildj[0])
                    elif ildj.ndim < scale.ndim - 2:
                        ildj = np.reshape(ildj, scale.shape[0:-2])
                    self.assertAllClose(
                        ildj,
                        bijector.inverse_log_det_jacobian(x).eval())
Example #2
0
    def testWeirdSampleNoBatchScalarViaIdentity(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = -1.
                # Corresponds to scale = 2.
                bijector = affine_lib.Affine(shift=mu,
                                             scale_identity_multiplier=2.,
                                             event_ndims=0)
                self.assertEqual(0, bijector.event_ndims.eval())  # "is scalar"
                x = [[1., 2, 3], [4, 5, 6]]  # Weird sample shape.
                self.assertAllClose([[1., 3, 5], [7, 9, 11]],
                                    run(bijector.forward, x))
                self.assertAllClose([[1., 1.5, 2.], [2.5, 3, 3.5]],
                                    run(bijector.inverse, x))
                self.assertAllClose(-np.log(2.),
                                    run(bijector.inverse_log_det_jacobian, x))
Example #3
0
    def testIdentityAndDiagWithTriL(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = -1.
                # scale = [[3., 0], [2, 4]]
                bijector = affine_lib.Affine(shift=mu,
                                             scale_identity_multiplier=1.0,
                                             scale_diag=[1., 2.],
                                             scale_tril=[[1., 0], [2., 1]])
                self.assertEqual(1, bijector.event_ndims.eval())  # "is vector"
                x = [[1., 2]]  # One multivariate sample.
                self.assertAllClose([[2., 9]], run(bijector.forward, x))
                self.assertAllClose([[2 / 3., 5 / 12.]],
                                    run(bijector.inverse, x))
                self.assertAllClose(-np.log(12.),
                                    run(bijector.inverse_log_det_jacobian, x))
Example #4
0
    def testBatchMultivariateFullDynamic(self):
        with self.test_session() as sess:
            x = array_ops.placeholder(dtypes.float32, name="x")
            mu = array_ops.placeholder(dtypes.float32, name="mu")
            scale_diag = array_ops.placeholder(dtypes.float32,
                                               name="scale_diag")
            event_ndims = array_ops.placeholder(dtypes.int32,
                                                name="event_ndims")

            x_value = np.array([[[1., 1]]], dtype=np.float32)
            mu_value = np.array([[1., -1]], dtype=np.float32)
            scale_diag_value = np.array([[2., 2]], dtype=np.float32)
            event_ndims_value = 1

            feed_dict = {
                x: x_value,
                mu: mu_value,
                scale_diag: scale_diag_value,
                event_ndims: event_ndims_value
            }

            bijector = affine_lib.Affine(shift=mu,
                                         scale_diag=scale_diag,
                                         event_ndims=event_ndims)
            self.assertEqual(1, sess.run(bijector.event_ndims, feed_dict))
            self.assertAllClose([[[3., 1]]],
                                sess.run(bijector.forward(x), feed_dict))
            self.assertAllClose([[[0., 1]]],
                                sess.run(bijector.inverse(x), feed_dict))
            self.assertAllClose([-np.log(4)],
                                sess.run(bijector.inverse_log_det_jacobian(x),
                                         feed_dict))
Example #5
0
    def testNoBatchMultivariateDiag(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = [1., -1]
                # Multivariate
                # Corresponds to scale = [[2., 0], [0, 1.]]
                bijector = affine_lib.Affine(shift=mu, scale_diag=[2., 1])
                self.assertEqual(1, bijector.event_ndims.eval())  # "is vector"
                x = [1., 1]
                # matmul(sigma, x) + shift
                # = [-1, -1] + [1, -1]
                self.assertAllClose([3., 0], run(bijector.forward, x))
                self.assertAllClose([0., 2], run(bijector.inverse, x))
                self.assertAllClose(-np.log(2.),
                                    run(bijector.inverse_log_det_jacobian, x))

                # x is a 2-batch of 2-vectors.
                # The first vector is [1, 1], the second is [-1, -1].
                # Each undergoes matmul(sigma, x) + shift.
                x = [[1., 1], [-1., -1]]
                self.assertAllClose([[3., 0], [-1., -2]],
                                    run(bijector.forward, x))
                self.assertAllClose([[0., 2], [-1., 0]],
                                    run(bijector.inverse, x))
                self.assertAllClose(-np.log(2.),
                                    run(bijector.inverse_log_det_jacobian, x))
Example #6
0
 def testScalarCongruency(self):
     with self.test_session():
         bijector = affine_lib.Affine(shift=3.6,
                                      scale_identity_multiplier=0.42,
                                      event_ndims=0)
         bijector_test_util.assert_scalar_congruency(bijector,
                                                     lower_x=-2.,
                                                     upper_x=2.)
Example #7
0
 def testEventNdimsLargerThanOneRaises(self):
     with self.test_session():
         mu = [1., -1]
         # Scale corresponds to 2x2 identity matrix.
         bijector = affine_lib.Affine(shift=mu,
                                      event_ndims=2,
                                      validate_args=True)
         bijector.forward([1., 1.]).eval()
Example #8
0
    def testScaleZeroScalarRaises(self):
        with self.test_session():
            mu = -1.
            # Check Identity matrix with zero scaling.
            bijector = affine_lib.Affine(shift=mu,
                                         scale_identity_multiplier=0.0,
                                         event_ndims=0,
                                         validate_args=True)
            with self.assertRaisesOpError("Condition x > 0"):
                bijector.forward(1.).eval()

            # Check Diag matrix with zero scaling.
            bijector = affine_lib.Affine(shift=mu,
                                         scale_diag=[0.0],
                                         event_ndims=0,
                                         validate_args=True)
            with self.assertRaisesOpError("Condition x > 0"):
                bijector.forward(1.).eval()
Example #9
0
 def testNoBatchMultivariateRaisesWhenSingular(self):
     with self.test_session():
         mu = [1., -1]
         bijector = affine_lib.Affine(
             shift=mu,
             # Has zero on the diagonal.
             scale_diag=[0., 1],
             validate_args=True)
         with self.assertRaisesOpError("Condition x > 0"):
             bijector.forward([1., 1.]).eval()
Example #10
0
    def testTriLWithVDVTUpdateNoDiagonal(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = -1.
                # Corresponds to scale = [[6, 0, 0], [1, 3, 0], [2, 3, 5]]
                bijector = affine_lib.Affine(shift=mu,
                                             scale_tril=[[2., 0, 0], [1, 3, 0],
                                                         [2, 3, 4]],
                                             scale_perturb_diag=None,
                                             scale_perturb_factor=[[2., 0],
                                                                   [0., 0],
                                                                   [0, 1]])
                bijector_ref = affine_lib.Affine(shift=mu,
                                                 scale_tril=[[6., 0, 0],
                                                             [1, 3, 0],
                                                             [2, 3, 5]])

                self.assertEqual(1, bijector.event_ndims.eval())  # "is vector"
                x = [1., 2, 3]  # Vector.
                self.assertAllClose([5., 6, 22], run(bijector.forward, x))
                self.assertAllClose(run(bijector_ref.forward, x),
                                    run(bijector.forward, x))
                self.assertAllClose([1 / 3., 8 / 9., 4 / 30.],
                                    run(bijector.inverse, x))
                self.assertAllClose(run(bijector_ref.inverse, x),
                                    run(bijector.inverse, x))
                self.assertAllClose(-np.log(90.),
                                    run(bijector.inverse_log_det_jacobian, x))
                self.assertAllClose(
                    run(bijector.inverse_log_det_jacobian, x),
                    run(bijector_ref.inverse_log_det_jacobian, x))
Example #11
0
    def testIdentityWithVDVTUpdate(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = -1.
                # Corresponds to scale = [[10, 0, 0], [0, 2, 0], [0, 0, 3]]
                bijector = affine_lib.Affine(shift=mu,
                                             scale_identity_multiplier=2.,
                                             scale_perturb_diag=[2., 1],
                                             scale_perturb_factor=[[2., 0],
                                                                   [0., 0],
                                                                   [0, 1]])
                bijector_ref = affine_lib.Affine(shift=mu,
                                                 scale_diag=[10., 2, 3])

                self.assertEqual(1, bijector.event_ndims.eval())  # "is vector"
                x = [1., 2, 3]  # Vector.
                self.assertAllClose([9., 3, 8], run(bijector.forward, x))
                self.assertAllClose(run(bijector_ref.forward, x),
                                    run(bijector.forward, x))

                self.assertAllClose([0.2, 1.5, 4 / 3.],
                                    run(bijector.inverse, x))
                self.assertAllClose(run(bijector_ref.inverse, x),
                                    run(bijector.inverse, x))
                self.assertAllClose(-np.log(60.),
                                    run(bijector.inverse_log_det_jacobian, x))
                self.assertAllClose(
                    run(bijector.inverse_log_det_jacobian, x),
                    run(bijector_ref.inverse_log_det_jacobian, x))
Example #12
0
    def testBatchMultivariateDiag(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value, dtype=np.float32)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = [[1., -1]]
                # Corresponds to 1 2x2 matrix, with twos on the diagonal.
                scale_diag = [[2., 2]]
                bijector = affine_lib.Affine(shift=mu, scale_diag=scale_diag)
                self.assertEqual(1, bijector.event_ndims.eval())  # "is vector"
                x = [[[1., 1]]]
                self.assertAllClose([[[3., 1]]], run(bijector.forward, x))
                self.assertAllClose([[[0., 1]]], run(bijector.inverse, x))
                self.assertAllClose([-np.log(4)],
                                    run(bijector.inverse_log_det_jacobian, x))
Example #13
0
    def testTwoBatchScalarIdentityViaIdentity(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = [1., -1]
                # Univariate, two batches.
                # Corresponds to scale = 1.
                bijector = affine_lib.Affine(shift=mu, event_ndims=0)
                self.assertEqual(0, bijector.event_ndims.eval())  # "is scalar"
                x = [1., 1]  # One sample from each of two batches.
                self.assertAllClose([2., 0], run(bijector.forward, x))
                self.assertAllClose([0., 2], run(bijector.inverse, x))
                self.assertAllClose(0.,
                                    run(bijector.inverse_log_det_jacobian, x))
Example #14
0
    def testNoBatchScalarViaDiag(self):
        with self.test_session() as sess:

            def static_run(fun, x):
                return fun(x).eval()

            def dynamic_run(fun, x_value):
                x_value = np.array(x_value)
                x = array_ops.placeholder(dtypes.float32, name="x")
                return sess.run(fun(x), feed_dict={x: x_value})

            for run in (static_run, dynamic_run):
                mu = -1.
                # Corresponds to scale = 2
                bijector = affine_lib.Affine(shift=mu,
                                             scale_diag=[2.],
                                             event_ndims=0)
                self.assertEqual(0, bijector.event_ndims.eval())  # "is scalar"
                x = [1., 2, 3]  # Three scalar samples (no batches).
                self.assertAllClose([1., 3, 5], run(bijector.forward, x))
                self.assertAllClose([1., 1.5, 2.], run(bijector.inverse, x))
                self.assertAllClose(-np.log(2.),
                                    run(bijector.inverse_log_det_jacobian, x))
Example #15
0
 def testScalePropertyAssertsCorrectly(self):
     with self.test_session():
         with self.assertRaises(NotImplementedError):
             scale = affine_lib.Affine(  # pylint:disable=unused-variable
                 scale_tril=[[1., 0], [2, 1]],
                 scale_perturb_factor=[2., 1.]).scale
Example #16
0
 def testProperties(self):
     with self.test_session():
         mu = -1.
         # scale corresponds to 1.
         bijector = affine_lib.Affine(shift=mu, event_ndims=0)
         self.assertEqual("affine", bijector.name)