Ejemplo n.º 1
0
    def test_is_non_singular_auto_set(self):
        # Matrix with two positive eigenvalues, 11 and 8.
        # The matrix values do not effect auto-setting of the flags.
        matrix = [[11., 0.], [1., 8.]]
        operator_1 = linalg.LinearOperatorFullMatrix(matrix,
                                                     is_non_singular=True)
        operator_2 = linalg.LinearOperatorFullMatrix(matrix,
                                                     is_non_singular=True)
        operator_3 = linalg.LinearOperatorFullMatrix(matrix,
                                                     is_non_singular=True)

        operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
            [[operator_1], [operator_2, operator_3]],
            is_positive_definite=False,  # No reason it HAS to be False...
            is_non_singular=None)
        self.assertFalse(operator.is_positive_definite)
        self.assertTrue(operator.is_non_singular)

        with self.assertRaisesRegex(ValueError, "always non-singular"):
            block_lower_triangular.LinearOperatorBlockLowerTriangular(
                [[operator_1], [operator_2, operator_3]],
                is_non_singular=False)

        operator_4 = linalg.LinearOperatorFullMatrix([[1., 0.], [2., 0.]],
                                                     is_non_singular=False)

        # A singular operator off of the main diagonal shouldn't raise
        block_lower_triangular.LinearOperatorBlockLowerTriangular(
            [[operator_1], [operator_4, operator_2]], is_non_singular=True)

        with self.assertRaisesRegex(ValueError, "always singular"):
            block_lower_triangular.LinearOperatorBlockLowerTriangular(
                [[operator_1], [operator_2, operator_4]], is_non_singular=True)
Ejemplo n.º 2
0
    def test_tape_safe(self):
        operator_1 = linalg.LinearOperatorFullMatrix(variables_module.Variable(
            [[1., 0.], [0., 1.]]),
                                                     is_self_adjoint=True,
                                                     is_positive_definite=True)
        operator_2 = linalg.LinearOperatorFullMatrix(
            variables_module.Variable([[2., 0.], [1., 0.]]))
        operator_3 = linalg.LinearOperatorFullMatrix(variables_module.Variable(
            [[3., 1.], [1., 3.]]),
                                                     is_self_adjoint=True,
                                                     is_positive_definite=True)
        operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
            [[operator_1], [operator_2, operator_3]],
            is_self_adjoint=False,
            is_positive_definite=True)

        diagonal_grads_only = [
            "diag_part", "trace", "determinant", "log_abs_determinant"
        ]
        self.check_tape_safe(operator, skip_options=diagonal_grads_only)

        for y in diagonal_grads_only:
            for diag_block in [operator_1, operator_3]:
                with backprop.GradientTape() as tape:
                    grads = tape.gradient(
                        getattr(operator, y)(), diag_block.variables)
                    for item in grads:
                        self.assertIsNotNone(item)
Ejemplo n.º 3
0
 def test_operators_wrong_length_raises(self):
     with self.assertRaisesRegex(ValueError, "must contain `2` blocks"):
         block_lower_triangular.LinearOperatorBlockLowerTriangular(
             [[linalg.LinearOperatorFullMatrix(rng.rand(2, 2))],
              [
                  linalg.LinearOperatorFullMatrix(rng.rand(2, 2))
                  for _ in range(3)
              ]])
 def test_operators_mismatched_dimension_raises(self):
   operators = [
       [linalg.LinearOperatorFullMatrix(rng.rand(3, 3))],
       [linalg.LinearOperatorFullMatrix(rng.rand(3, 4)),
        linalg.LinearOperatorFullMatrix(rng.rand(3, 3))]
   ]
   with self.assertRaisesRegexp(ValueError, "must be equal"):
     block_lower_triangular.LinearOperatorBlockLowerTriangular(operators)
 def test_non_square_operator_raises(self):
   operators = [
       [linalg.LinearOperatorFullMatrix(rng.rand(3, 4), is_square=False)],
       [linalg.LinearOperatorFullMatrix(rng.rand(4, 4)),
        linalg.LinearOperatorFullMatrix(rng.rand(4, 4))]
   ]
   with self.assertRaisesRegexp(ValueError, "must be square"):
     block_lower_triangular.LinearOperatorBlockLowerTriangular(operators)
 def test_different_dtypes_raises(self):
   operators = [
       [linalg.LinearOperatorFullMatrix(rng.rand(2, 3, 3))],
       [linalg.LinearOperatorFullMatrix(rng.rand(2, 3, 3)),
        linalg.LinearOperatorFullMatrix(rng.rand(2, 3, 3).astype(np.float32))]
   ]
   with self.assertRaisesRegexp(TypeError, "same dtype"):
     block_lower_triangular.LinearOperatorBlockLowerTriangular(operators)
Ejemplo n.º 7
0
 def test_is_x_flags(self):
     # Matrix with two positive eigenvalues, 1, and 1.
     # The matrix values do not effect auto-setting of the flags.
     matrix = [[1., 0.], [1., 1.]]
     operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
         [[linalg.LinearOperatorFullMatrix(matrix)]],
         is_positive_definite=True,
         is_non_singular=True,
         is_self_adjoint=False)
     self.assertTrue(operator.is_positive_definite)
     self.assertTrue(operator.is_non_singular)
     self.assertFalse(operator.is_self_adjoint)
  def operator_and_matrix(
      self, shape_info, dtype, use_placeholder,
      ensure_self_adjoint_and_pd=False):

    expected_blocks = (
        shape_info.__dict__["blocks"] if "blocks" in shape_info.__dict__
        else [[list(shape_info.shape)]])

    matrices = []
    for i, row_shapes in enumerate(expected_blocks):
      row = []
      for j, block_shape in enumerate(row_shapes):
        if i == j:  # operator is on the diagonal
          row.append(
              linear_operator_test_util.random_positive_definite_matrix(
                  block_shape, dtype, force_well_conditioned=True))
        else:
          row.append(
              linear_operator_test_util.random_normal(block_shape, dtype=dtype))
      matrices.append(row)

    lin_op_matrices = matrices

    if use_placeholder:
      lin_op_matrices = [[
          array_ops.placeholder_with_default(
              matrix, shape=None) for matrix in row] for row in matrices]

    operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
        [[linalg.LinearOperatorFullMatrix(  # pylint:disable=g-complex-comprehension
            l,
            is_square=True,
            is_self_adjoint=True if ensure_self_adjoint_and_pd else None,
            is_positive_definite=True if ensure_self_adjoint_and_pd else None)
          for l in row] for row in lin_op_matrices])

    # Should be auto-set.
    self.assertTrue(operator.is_square)

    # Broadcast the shapes.
    expected_shape = list(shape_info.shape)
    broadcasted_matrices = linear_operator_util.broadcast_matrix_batch_dims(
        [op for row in matrices for op in row])  # pylint: disable=g-complex-comprehension
    matrices = [broadcasted_matrices[i * (i + 1) // 2:(i + 1) * (i + 2) // 2]
                for i in range(len(matrices))]

    block_lower_triangular_dense = _block_lower_triangular_dense(
        expected_shape, matrices)

    if not use_placeholder:
      block_lower_triangular_dense.set_shape(expected_shape)

    return operator, block_lower_triangular_dense
 def test_block_lower_triangular_inverse_type(self):
   matrix = [[1., 0.], [0., 1.]]
   operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
       [[linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True)],
        [linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True),
         linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True)]],
       is_non_singular=True,
   )
   inverse = operator.inverse()
   self.assertIsInstance(
       inverse,
       block_lower_triangular.LinearOperatorBlockLowerTriangular)
   self.assertEqual(2, len(inverse.operators))
   self.assertEqual(1, len(inverse.operators[0]))
   self.assertEqual(2, len(inverse.operators[1]))
Ejemplo n.º 10
0
 def test_convert_variables_to_tensors(self):
     operator_1 = linalg.LinearOperatorFullMatrix(variables_module.Variable(
         [[1., 0.], [0., 1.]]),
                                                  is_self_adjoint=True,
                                                  is_positive_definite=True)
     operator_2 = linalg.LinearOperatorFullMatrix(
         variables_module.Variable([[2., 0.], [1., 0.]]))
     operator_3 = linalg.LinearOperatorFullMatrix(variables_module.Variable(
         [[3., 1.], [1., 3.]]),
                                                  is_self_adjoint=True,
                                                  is_positive_definite=True)
     operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
         [[operator_1], [operator_2, operator_3]],
         is_self_adjoint=False,
         is_positive_definite=True)
     with self.cached_session() as sess:
         sess.run([x.initializer for x in operator.variables])
         self.check_convert_variables_to_tensors(operator)
Ejemplo n.º 11
0
 def test_incompatible_input_blocks_raises(self):
     matrix_1 = array_ops.placeholder_with_default(rng.rand(4, 4),
                                                   shape=None)
     matrix_2 = array_ops.placeholder_with_default(rng.rand(3, 4),
                                                   shape=None)
     matrix_3 = array_ops.placeholder_with_default(rng.rand(3, 3),
                                                   shape=None)
     operators = [[
         linalg.LinearOperatorFullMatrix(matrix_1, is_square=True)
     ],
                  [
                      linalg.LinearOperatorFullMatrix(matrix_2),
                      linalg.LinearOperatorFullMatrix(matrix_3,
                                                      is_square=True)
                  ]]
     operator = block_lower_triangular.LinearOperatorBlockLowerTriangular(
         operators)
     x = np.random.rand(2, 4, 5).tolist()
     msg = ("dimension does not match" if context.executing_eagerly() else
            "input structure is ambiguous")
     with self.assertRaisesRegex(ValueError, msg):
         operator.matmul(x)
Ejemplo n.º 12
0
 def test_empty_operators_raises(self):
     with self.assertRaisesRegex(ValueError, "must be a list of >=1"):
         block_lower_triangular.LinearOperatorBlockLowerTriangular([])
 def test_empty_operators_raises(self):
   with self.assertRaisesRegexp(ValueError, "non-empty"):
     block_lower_triangular.LinearOperatorBlockLowerTriangular([])