def test_diag_solve(self):
        operator1 = linalg_lib.LinearOperatorDiag([2., 3.],
                                                  is_non_singular=True)
        operator2 = linalg_lib.LinearOperatorDiag([1., 2.],
                                                  is_non_singular=True)
        operator3 = linalg_lib.LinearOperatorScaledIdentity(
            num_rows=2, multiplier=3., is_non_singular=True)
        operator_solve = operator1.solve(operator2)
        self.assertTrue(
            isinstance(operator_solve, linalg_lib.LinearOperatorDiag))
        self.assertAllClose([0.5, 2 / 3.], self.evaluate(operator_solve.diag))

        operator_solve = operator2.solve(operator1)
        self.assertTrue(
            isinstance(operator_solve, linalg_lib.LinearOperatorDiag))
        self.assertAllClose([2., 3 / 2.], self.evaluate(operator_solve.diag))

        operator_solve = operator1.solve(operator3)
        self.assertTrue(
            isinstance(operator_solve, linalg_lib.LinearOperatorDiag))
        self.assertAllClose([3 / 2., 1.], self.evaluate(operator_solve.diag))

        operator_solve = operator3.solve(operator1)
        self.assertTrue(
            isinstance(operator_solve, linalg_lib.LinearOperatorDiag))
        self.assertAllClose([2 / 3., 1.], self.evaluate(operator_solve.diag))
Exemplo n.º 2
0
  def test_diag_matmul(self):
    operator1 = linalg_lib.LinearOperatorDiag([2., 3.])
    operator2 = linalg_lib.LinearOperatorDiag([1., 2.])
    operator3 = linalg_lib.LinearOperatorScaledIdentity(
        num_rows=2, multiplier=3.)
    operator_matmul = operator1.matmul(operator2)
    self.assertTrue(isinstance(
        operator_matmul,
        linalg_lib.LinearOperatorDiag))
    self.assertAllClose([2., 6.], self.evaluate(operator_matmul.diag))

    operator_matmul = operator2.matmul(operator1)
    self.assertTrue(isinstance(
        operator_matmul,
        linalg_lib.LinearOperatorDiag))
    self.assertAllClose([2., 6.], self.evaluate(operator_matmul.diag))

    operator_matmul = operator1.matmul(operator3)
    self.assertTrue(isinstance(
        operator_matmul,
        linalg_lib.LinearOperatorDiag))
    self.assertAllClose([6., 9.], self.evaluate(operator_matmul.diag))

    operator_matmul = operator3.matmul(operator1)
    self.assertTrue(isinstance(
        operator_matmul,
        linalg_lib.LinearOperatorDiag))
    self.assertAllClose([6., 9.], self.evaluate(operator_matmul.diag))
    def test_triangular_diag_matmul(self):
        operator1 = linalg_lib.LinearOperatorLowerTriangular([[1., 0., 0.],
                                                              [2., 1., 0.],
                                                              [2., 3., 3.]])
        operator2 = linalg_lib.LinearOperatorDiag([2., 2., 3.])
        operator_matmul = operator1.matmul(operator2)
        self.assertTrue(
            isinstance(operator_matmul,
                       linalg_lib.LinearOperatorLowerTriangular))
        self.assertAllClose(
            math_ops.matmul(operator1.to_dense(), operator2.to_dense()),
            self.evaluate(operator_matmul.to_dense()))

        operator_matmul = operator2.matmul(operator1)
        self.assertTrue(
            isinstance(operator_matmul,
                       linalg_lib.LinearOperatorLowerTriangular))
        self.assertAllClose(
            math_ops.matmul(operator2.to_dense(), operator1.to_dense()),
            self.evaluate(operator_matmul.to_dense()))
Exemplo n.º 4
0
    def testDiag(self):
        with self.cached_session():
            shift = np.array([-1, 0, 1], dtype=np.float32)
            diag = np.array([[1, 2, 3], [2, 5, 6]], dtype=np.float32)
            scale = linalg.LinearOperatorDiag(diag, is_non_singular=True)
            affine = AffineLinearOperator(shift=shift,
                                          scale=scale,
                                          validate_args=True)

            x = np.array([[1, 0, -1], [2, 3, 4]], dtype=np.float32)
            y = diag * x + shift
            ildj = -np.sum(np.log(np.abs(diag)), axis=-1)

            self.assertEqual(affine.name, "affine_linear_operator")
            self.assertAllClose(y, affine.forward(x).eval())
            self.assertAllClose(x, affine.inverse(y).eval())
            self.assertAllClose(
                ildj,
                affine.inverse_log_det_jacobian(y, event_ndims=1).eval())
            self.assertAllClose(
                -affine.inverse_log_det_jacobian(y, event_ndims=1).eval(),
                affine.forward_log_det_jacobian(x, event_ndims=1).eval())
def make_diag_scale(loc=None,
                    scale_diag=None,
                    scale_identity_multiplier=None,
                    shape_hint=None,
                    validate_args=False,
                    assert_positive=False,
                    name=None):
    """Creates a LinOp representing a diagonal matrix.

  Args:
    loc: Floating-point `Tensor`. This is used for inferring shape in the case
      where only `scale_identity_multiplier` is set.
    scale_diag: Floating-point `Tensor` representing the diagonal matrix.
      `scale_diag` has shape [N1, N2, ...  k], which represents a k x k
      diagonal matrix.
      When `None` no diagonal term is added to the LinOp.
    scale_identity_multiplier: floating point rank 0 `Tensor` representing a
      scaling done to the identity matrix.
      When `scale_identity_multiplier = scale_diag = scale_tril = None` then
      `scale += IdentityMatrix`. Otherwise no scaled-identity-matrix is added
      to `scale`.
    shape_hint: scalar integer `Tensor` representing a hint at the dimension of
      the identity matrix when only `scale_identity_multiplier` is set.
    validate_args: Python `bool` indicating whether arguments should be
      checked for correctness.
    assert_positive: Python `bool` indicating whether LinOp should be checked
      for being positive definite.
    name: Python `str` name given to ops managed by this object.

  Returns:
    `LinearOperator` representing a lower triangular matrix.

  Raises:
    ValueError:  If only `scale_identity_multiplier` is set and `loc` and
      `shape_hint` are both None.
  """
    def _maybe_attach_assertion(x):
        if not validate_args:
            return x
        if assert_positive:
            return control_flow_ops.with_dependencies([
                check_ops.assert_positive(
                    x, message="diagonal part must be positive"),
            ], x)
        return control_flow_ops.with_dependencies([
            check_ops.assert_none_equal(
                x,
                array_ops.zeros([], x.dtype),
                message="diagonal part must be non-zero")
        ], x)

    with ops.name_scope(name,
                        "make_diag_scale",
                        values=[loc, scale_diag, scale_identity_multiplier]):
        loc = _convert_to_tensor(loc, name="loc")
        scale_diag = _convert_to_tensor(scale_diag, name="scale_diag")
        scale_identity_multiplier = _convert_to_tensor(
            scale_identity_multiplier, name="scale_identity_multiplier")

        if scale_diag is not None:
            if scale_identity_multiplier is not None:
                scale_diag += scale_identity_multiplier[..., array_ops.newaxis]
            return linalg.LinearOperatorDiag(
                diag=_maybe_attach_assertion(scale_diag),
                is_non_singular=True,
                is_self_adjoint=True,
                is_positive_definite=assert_positive)

        if loc is None and shape_hint is None:
            raise ValueError("Cannot infer `event_shape` unless `loc` or "
                             "`shape_hint` is specified.")

        if shape_hint is None:
            shape_hint = loc.shape[-1]

        if scale_identity_multiplier is None:
            return linalg.LinearOperatorIdentity(
                num_rows=shape_hint,
                dtype=loc.dtype.base_dtype,
                is_self_adjoint=True,
                is_positive_definite=True,
                assert_proper_shapes=validate_args)

        return linalg.LinearOperatorScaledIdentity(
            num_rows=shape_hint,
            multiplier=_maybe_attach_assertion(scale_identity_multiplier),
            is_non_singular=True,
            is_self_adjoint=True,
            is_positive_definite=assert_positive,
            assert_proper_shapes=validate_args)