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.assertRaisesRegexp(TypeError, "same dtype"): kronecker.LinearOperatorKronecker(operators)
def _operator_and_matrix(self, build_info, dtype, use_placeholder): shape = list(build_info.shape) expected_factors = build_info.__dict__["factors"] matrices = [ linear_operator_test_util.random_positive_definite_matrix( block_shape, dtype, force_well_conditioned=True) for block_shape in expected_factors ] lin_op_matrices = matrices if use_placeholder: lin_op_matrices = [ array_ops.placeholder_with_default(m, shape=None) for m in matrices] operator = kronecker.LinearOperatorKronecker( [linalg.LinearOperatorFullMatrix( l, is_square=True) for l in lin_op_matrices]) matrices = linear_operator_util.broadcast_matrix_batch_dims(matrices) kronecker_dense = _kronecker_dense(matrices) if not use_placeholder: kronecker_dense.set_shape(shape) return operator, kronecker_dense
def test_kronecker_cholesky_type(self): matrix = [[1., 0.], [0., 1.]] operator = kronecker.LinearOperatorKronecker( [ 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, kronecker.LinearOperatorKronecker) 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_name(self): matrix = [[11., 0.], [1., 8.]] operator_1 = linalg.LinearOperatorFullMatrix(matrix, name="left") operator_2 = linalg.LinearOperatorFullMatrix(matrix, name="right") operator = kronecker.LinearOperatorKronecker([operator_1, operator_2]) self.assertEqual("left_x_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 = kronecker.LinearOperatorKronecker( [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.assertRaisesRegexp(ValueError, "always non-singular"): kronecker.LinearOperatorKronecker( [operator_1, operator_2], is_non_singular=False)
def _cholesky_kronecker(kronecker_operator): # Cholesky decomposition of a Kronecker product is the Kronecker product # of cholesky decompositions. return linear_operator_kronecker.LinearOperatorKronecker( operators=[ operator.cholesky() for operator in kronecker_operator.operators], is_non_singular=True, is_self_adjoint=False, is_square=True)
def _inverse_kronecker(kronecker_operator): # Inverse decomposition of a Kronecker product is the Kronecker product # of inverse decompositions. return linear_operator_kronecker.LinearOperatorKronecker( operators=[ operator.inverse() for operator in kronecker_operator.operators], is_non_singular=kronecker_operator.is_non_singular, is_self_adjoint=kronecker_operator.is_self_adjoint, is_positive_definite=kronecker_operator.is_positive_definite, is_square=True)
def _adjoint_kronecker(kronecker_operator): # Adjoint of a Kronecker product is the Kronecker product # of adjoints. return linear_operator_kronecker.LinearOperatorKronecker( operators=[ operator.adjoint() for operator in kronecker_operator.operators], is_non_singular=kronecker_operator.is_non_singular, is_self_adjoint=kronecker_operator.is_self_adjoint, is_positive_definite=kronecker_operator.is_positive_definite, is_square=True)
def _operator_and_mat_and_feed_dict(self, build_info, dtype, use_placeholder): shape = list(build_info.shape) expected_factors = build_info.__dict__["factors"] matrices = [ linear_operator_test_util.random_positive_definite_matrix( block_shape, dtype, force_well_conditioned=True) for block_shape in expected_factors ] if use_placeholder: matrices_ph = [ array_ops.placeholder(dtype=dtype) for _ in expected_factors ] # 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 = kronecker.LinearOperatorKronecker([ 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 = kronecker.LinearOperatorKronecker([ linalg.LinearOperatorFullMatrix(m, is_square=True) for m in matrices ]) feed_dict = None # Should be auto-set. self.assertTrue(operator.is_square) matrices = linear_operator_util.broadcast_matrix_batch_dims(matrices) kronecker_dense = _kronecker_dense(matrices) if not use_placeholder: kronecker_dense.set_shape(shape) return operator, kronecker_dense, feed_dict
def test_kronecker_inverse_type(self): matrix = [[1., 0.], [0., 1.]] operator = kronecker.LinearOperatorKronecker( [ linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True), linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True), ], is_non_singular=True, ) inverse = operator.inverse() self.assertIsInstance(inverse, kronecker.LinearOperatorKronecker) self.assertEqual(2, len(inverse.operators))
def test_kronecker_adjoint_type(self): matrix = [[1., 0.], [0., 1.]] operator = kronecker.LinearOperatorKronecker( [ linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True), linalg.LinearOperatorFullMatrix(matrix, is_non_singular=True), ], is_non_singular=True, ) adjoint = operator.adjoint() self.assertIsInstance(adjoint, kronecker.LinearOperatorKronecker) self.assertEqual(2, len(adjoint.operators))
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 = kronecker.LinearOperatorKronecker( [linalg.LinearOperatorFullMatrix(matrix), 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_tape_safe(self): matrix_1 = variables_module.Variable([[1., 0.], [0., 1.]]) matrix_2 = variables_module.Variable([[2., 0.], [0., 2.]]) operator = kronecker.LinearOperatorKronecker( [ linalg.LinearOperatorFullMatrix(matrix_1, is_non_singular=True), linalg.LinearOperatorFullMatrix(matrix_2, is_non_singular=True), ], is_non_singular=True, ) self.check_tape_safe(operator)
def test_convert_variables_to_tensors(self): matrix_1 = variables_module.Variable([[1., 0.], [0., 1.]]) matrix_2 = variables_module.Variable([[2., 0.], [0., 2.]]) operator = kronecker.LinearOperatorKronecker( [ linalg.LinearOperatorFullMatrix(matrix_1, is_non_singular=True), linalg.LinearOperatorFullMatrix(matrix_2, is_non_singular=True), ], is_non_singular=True, ) with self.cached_session() as sess: sess.run([x.initializer for x in operator.variables]) self.check_convert_variables_to_tensors(operator)
def operator_and_matrix(self, build_info, dtype, use_placeholder, ensure_self_adjoint_and_pd=False): # Kronecker products constructed below will be from symmetric # positive-definite matrices. del ensure_self_adjoint_and_pd shape = list(build_info.shape) expected_factors = build_info.__dict__["factors"] matrices = [ linear_operator_test_util.random_positive_definite_matrix( block_shape, dtype, force_well_conditioned=True) for block_shape in expected_factors ] lin_op_matrices = matrices if use_placeholder: lin_op_matrices = [ array_ops.placeholder_with_default(m, shape=None) for m in matrices ] operator = kronecker.LinearOperatorKronecker([ linalg.LinearOperatorFullMatrix(l, is_square=True, is_self_adjoint=True, is_positive_definite=True) for l in lin_op_matrices ]) matrices = linear_operator_util.broadcast_matrix_batch_dims(matrices) kronecker_dense = _kronecker_dense(matrices) if not use_placeholder: kronecker_dense.set_shape(shape) return operator, kronecker_dense
def test_empty_or_one_operators_raises(self): with self.assertRaisesRegexp(ValueError, ">=1 operators"): kronecker.LinearOperatorKronecker([])