Ejemplo n.º 1
0
    def test_block_diag_solve_type(self):
        matrices1 = []
        matrices2 = []
        for i in range(1, 5):
            matrices1.append(
                linalg.LinearOperatorFullMatrix(
                    linear_operator_test_util.random_tril_matrix(
                        [i, i],
                        dtype=dtypes.float32,
                        force_well_conditioned=True)))

            matrices2.append(
                linalg.LinearOperatorFullMatrix(
                    linear_operator_test_util.random_normal(
                        [i, 3], dtype=dtypes.float32)))

        operator1 = block_diag.LinearOperatorBlockDiag(matrices1)
        operator2 = block_diag.LinearOperatorBlockDiag(matrices2,
                                                       is_square=False)

        expected_matrix = linalg.solve(operator1.to_dense(),
                                       operator2.to_dense())
        actual_operator = operator1.solve(operator2)

        self.assertIsInstance(actual_operator,
                              block_diag.LinearOperatorBlockDiag)
        actual_, expected_ = self.evaluate(
            [actual_operator.to_dense(), expected_matrix])
        self.assertAllClose(actual_, expected_)
Ejemplo n.º 2
0
    def test_block_diag_matmul_type(self):
        matrices1 = []
        matrices2 = []
        for i in range(1, 5):
            matrices1.append(
                linalg.LinearOperatorFullMatrix(
                    linear_operator_test_util.random_normal(
                        [2, i], dtype=dtypes.float32)))

            matrices2.append(
                linalg.LinearOperatorFullMatrix(
                    linear_operator_test_util.random_normal(
                        [i, 3], dtype=dtypes.float32)))

        operator1 = block_diag.LinearOperatorBlockDiag(matrices1,
                                                       is_square=False)
        operator2 = block_diag.LinearOperatorBlockDiag(matrices2,
                                                       is_square=False)

        expected_matrix = math_ops.matmul(operator1.to_dense(),
                                          operator2.to_dense())
        actual_operator = operator1.matmul(operator2)

        self.assertIsInstance(actual_operator,
                              block_diag.LinearOperatorBlockDiag)
        actual_, expected_ = self.evaluate(
            [actual_operator.to_dense(), expected_matrix])
        self.assertAllClose(actual_, expected_)
 def test_block_diag_cholesky_type(self):
     matrix = [[1., 0.], [0., 1.]]
     operator = block_diag.LinearOperatorBlockDiag(
         [
             linalg.LinearOperatorFullMatrix(
                 matrix,
                 is_positive_definite=True,
                 is_self_adjoint=True,
             ),
             linalg.LinearOperatorFullMatrix(
                 matrix,
                 is_positive_definite=True,
                 is_self_adjoint=True,
             ),
         ],
         is_positive_definite=True,
         is_self_adjoint=True,
     )
     cholesky_factor = operator.cholesky()
     self.assertIsInstance(cholesky_factor,
                           block_diag.LinearOperatorBlockDiag)
     self.assertEqual(2, len(cholesky_factor.operators))
     self.assertIsInstance(cholesky_factor.operators[0],
                           lower_triangular.LinearOperatorLowerTriangular)
     self.assertIsInstance(cholesky_factor.operators[1],
                           lower_triangular.LinearOperatorLowerTriangular)
 def test_different_dtypes_raises(self):
   operators = [
       linalg.LinearOperatorFullMatrix(rng.rand(2, 3, 3)),
       linalg.LinearOperatorFullMatrix(rng.rand(2, 3, 3).astype(np.float32))
   ]
   with self.assertRaisesRegex(TypeError, "same dtype"):
     block_diag.LinearOperatorBlockDiag(operators)
Ejemplo n.º 5
0
 def test_is_x_parameters(self):
     matrix = [[1., 0.], [1., 1.]]
     sub_operator = linalg.LinearOperatorFullMatrix(matrix)
     operator = block_diag.LinearOperatorBlockDiag(
         [sub_operator],
         is_positive_definite=True,
         is_non_singular=True,
         is_self_adjoint=False)
     self.assertEqual(
         operator.parameters, {
             "name": None,
             "is_square": True,
             "is_positive_definite": True,
             "is_self_adjoint": False,
             "is_non_singular": True,
             "operators": [sub_operator],
         })
     self.assertEqual(
         sub_operator.parameters, {
             "is_non_singular": None,
             "is_positive_definite": None,
             "is_self_adjoint": None,
             "is_square": None,
             "matrix": matrix,
             "name": "LinearOperatorFullMatrix",
         })
 def test_non_square_operator_raises(self):
     operators = [
         linalg.LinearOperatorFullMatrix(rng.rand(3, 4), is_square=False),
         linalg.LinearOperatorFullMatrix(rng.rand(3, 3))
     ]
     with self.assertRaisesRegexp(ValueError, "square matrices"):
         block_diag.LinearOperatorBlockDiag(operators)
Ejemplo n.º 7
0
def _cholesky_block_diag(block_diag_operator):
    # We take the cholesky of each block on the diagonal.
  return linear_operator_block_diag.LinearOperatorBlockDiag(
      operators=[
          operator.cholesky() for operator in block_diag_operator.operators],
      is_non_singular=True,
      is_self_adjoint=False,
      is_square=True)
    def test_name(self):
        matrix = [[11., 0.], [1., 8.]]
        operator_1 = linalg.LinearOperatorFullMatrix(matrix, name="left")
        operator_2 = linalg.LinearOperatorFullMatrix(matrix, name="right")

        operator = block_diag.LinearOperatorBlockDiag([operator_1, operator_2])

        self.assertEqual("left_ds_right", operator.name)
  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 = block_diag.LinearOperatorBlockDiag(
        [operator_1, operator_2],
        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_diag.LinearOperatorBlockDiag(
          [operator_1, operator_2], is_non_singular=False)
    def _operator_and_mat_and_feed_dict(self, build_info, dtype,
                                        use_placeholder):
        shape = list(build_info.shape)
        expected_blocks = (build_info.__dict__["blocks"]
                           if "blocks" in build_info.__dict__ else [shape])
        matrices = [
            linear_operator_test_util.random_positive_definite_matrix(
                block_shape, dtype, force_well_conditioned=True)
            for block_shape in expected_blocks
        ]

        if use_placeholder:
            matrices_ph = [
                array_ops.placeholder(dtype=dtype) for _ in expected_blocks
            ]
            # Evaluate here because (i) you cannot feed a tensor, and (ii)
            # values are random and we want the same value used for both mat and
            # feed_dict.
            matrices = self.evaluate(matrices)
            operator = block_diag.LinearOperatorBlockDiag([
                linalg.LinearOperatorFullMatrix(m_ph, is_square=True)
                for m_ph in matrices_ph
            ],
                                                          is_square=True)
            feed_dict = {m_ph: m for (m_ph, m) in zip(matrices_ph, matrices)}
        else:
            operator = block_diag.LinearOperatorBlockDiag([
                linalg.LinearOperatorFullMatrix(m, is_square=True)
                for m in matrices
            ])
            feed_dict = None
            # Should be auto-set.
            self.assertTrue(operator.is_square)

        # Broadcast the shapes.
        expected_shape = list(build_info.shape)

        matrices = linear_operator_util.broadcast_matrix_batch_dims(matrices)

        block_diag_dense = _block_diag_dense(expected_shape, matrices)

        if not use_placeholder:
            block_diag_dense.set_shape(
                expected_shape[:-2] + [expected_shape[-1], expected_shape[-1]])

        return operator, block_diag_dense, feed_dict
Ejemplo n.º 11
0
def _inverse_block_diag(block_diag_operator):
  # We take the inverse of each block on the diagonal.
  return linear_operator_block_diag.LinearOperatorBlockDiag(
      operators=[
          operator.inverse() for operator in block_diag_operator.operators],
      is_non_singular=block_diag_operator.is_non_singular,
      is_self_adjoint=block_diag_operator.is_self_adjoint,
      is_positive_definite=block_diag_operator.is_positive_definite,
      is_square=True)
 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_diag.LinearOperatorBlockDiag(
         [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 test_block_diag_solve_raises(self):
    matrices1 = []
    for i in range(1, 5):
      matrices1.append(linalg.LinearOperatorFullMatrix(
          linear_operator_test_util.random_normal(
              [i, i], dtype=dtypes.float32)))
    operator1 = block_diag.LinearOperatorBlockDiag(matrices1)
    operator2 = linalg.LinearOperatorFullMatrix(
        linear_operator_test_util.random_normal(
            [15, 3], dtype=dtypes.float32))

    with self.assertRaisesRegex(ValueError, "Operators are incompatible"):
      operator1.solve(operator2)
 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, 3), shape=None)
   operators = [
       linalg.LinearOperatorFullMatrix(matrix_1, is_square=True),
       linalg.LinearOperatorFullMatrix(matrix_2, is_square=True)
   ]
   operator = block_diag.LinearOperatorBlockDiag(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)
def _solve_linear_operator_block_diag_block_diag(linop_a, linop_b):
    return linear_operator_block_diag.LinearOperatorBlockDiag(
        operators=[
            o1.solve(o2)
            for o1, o2 in zip(linop_a.operators, linop_b.operators)
        ],
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_a, linop_b),
        # In general, a solve of self-adjoint positive-definite block diagonal
        # matrices is not self-=adjoint.
        is_self_adjoint=None,
        # In general, a solve of positive-definite block diagonal matrices is
        # not positive-definite.
        is_positive_definite=None,
        is_square=True)
  def test_tape_safe(self):
    matrices = []
    for _ in range(4):
      matrices.append(variables_module.Variable(
          linear_operator_test_util.random_positive_definite_matrix(
              [2, 2], dtype=dtypes.float32, force_well_conditioned=True)))

    operator = block_diag.LinearOperatorBlockDiag(
        [linalg.LinearOperatorFullMatrix(
            matrix, is_self_adjoint=True,
            is_positive_definite=True) for matrix in matrices],
        is_self_adjoint=True,
        is_positive_definite=True,
    )
    self.check_tape_safe(operator)
    def _operator_and_matrix(self,
                             build_info,
                             dtype,
                             use_placeholder,
                             ensure_self_adjoint_and_pd=False):
        shape = list(build_info.shape)
        expected_blocks = (build_info.__dict__["blocks"]
                           if "blocks" in build_info.__dict__ else [shape])
        matrices = [
            linear_operator_test_util.random_positive_definite_matrix(
                block_shape, dtype, force_well_conditioned=True)
            for block_shape in expected_blocks
        ]

        lin_op_matrices = matrices

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

        operator = block_diag.LinearOperatorBlockDiag([
            linalg.LinearOperatorFullMatrix(
                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 lin_op_matrices
        ])

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

        # Broadcast the shapes.
        expected_shape = list(build_info.shape)

        matrices = linear_operator_util.broadcast_matrix_batch_dims(matrices)

        block_diag_dense = _block_diag_dense(expected_shape, matrices)

        if not use_placeholder:
            block_diag_dense.set_shape(
                expected_shape[:-2] + [expected_shape[-1], expected_shape[-1]])

        return operator, block_diag_dense
  def test_convert_variables_to_tensors(self):
    matrices = []
    for _ in range(3):
      matrices.append(variables_module.Variable(
          linear_operator_test_util.random_positive_definite_matrix(
              [3, 3], dtype=dtypes.float32, force_well_conditioned=True)))

    operator = block_diag.LinearOperatorBlockDiag(
        [linalg.LinearOperatorFullMatrix(
            matrix, is_self_adjoint=True,
            is_positive_definite=True) for matrix in matrices],
        is_self_adjoint=True,
        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.º 19
0
 def test_block_diag_adjoint_type(self):
     matrix = [[1., 0.], [0., 1.]]
     operator = block_diag.LinearOperatorBlockDiag(
         [
             linalg.LinearOperatorFullMatrix(
                 matrix,
                 is_non_singular=True,
             ),
             linalg.LinearOperatorFullMatrix(
                 matrix,
                 is_non_singular=True,
             ),
         ],
         is_non_singular=True,
     )
     adjoint = operator.adjoint()
     self.assertIsInstance(adjoint, block_diag.LinearOperatorBlockDiag)
     self.assertEqual(2, len(adjoint.operators))
 def test_block_diag_inverse_type(self):
     matrix = [[1., 0.], [0., 1.]]
     operator = block_diag.LinearOperatorBlockDiag(
         [
             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_diag.LinearOperatorBlockDiag)
     self.assertEqual(2, len(inverse.operators))
Ejemplo n.º 21
0
 def test_tape_safe(self):
     matrix = variables_module.Variable([[1., 0.], [0., 1.]])
     operator = block_diag.LinearOperatorBlockDiag(
         [
             linalg.LinearOperatorFullMatrix(
                 matrix,
                 is_self_adjoint=True,
                 is_positive_definite=True,
             ),
             linalg.LinearOperatorFullMatrix(
                 matrix,
                 is_self_adjoint=True,
                 is_positive_definite=True,
             ),
         ],
         is_self_adjoint=True,
         is_positive_definite=True,
     )
     self.check_tape_safe(operator)
Ejemplo n.º 22
0
    def operator_and_matrix(self,
                            shape_info,
                            dtype,
                            use_placeholder,
                            ensure_self_adjoint_and_pd=False):
        del ensure_self_adjoint_and_pd
        shape = list(shape_info.shape)
        expected_blocks = (shape_info.__dict__["blocks"]
                           if "blocks" in shape_info.__dict__ else [shape])
        matrices = [
            linear_operator_test_util.random_normal(block_shape, dtype=dtype)
            for block_shape in expected_blocks
        ]

        lin_op_matrices = matrices

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

        blocks = []
        for l in lin_op_matrices:
            blocks.append(
                linalg.LinearOperatorFullMatrix(l,
                                                is_square=False,
                                                is_self_adjoint=False,
                                                is_positive_definite=False))
        operator = block_diag.LinearOperatorBlockDiag(blocks)

        # Broadcast the shapes.
        expected_shape = list(shape_info.shape)

        matrices = linear_operator_util.broadcast_matrix_batch_dims(matrices)

        block_diag_dense = _block_diag_dense(expected_shape, matrices)

        if not use_placeholder:
            block_diag_dense.set_shape(expected_shape)

        return operator, block_diag_dense
 def test_empty_operators_raises(self):
     with self.assertRaisesRegexp(ValueError, "non-empty"):
         block_diag.LinearOperatorBlockDiag([])