def test_eigvalsh(self): with self.test_session(graph=ops.Graph()) as sess: sess.graph.seed = random_seed.DEFAULT_GRAPH_SEED operator, mat = self.operator_and_matrix( shapes_info, dtype, use_placeholder=use_placeholder, ensure_self_adjoint_and_pd=True) # Eigenvalues are real, so we'll cast these to float64 and sort # for comparison. op_eigvals = sort_ops.sort(math_ops.cast(operator.eigvals(), dtype=dtypes.float64), axis=-1) if dtype.is_complex: mat = math_ops.cast(mat, dtype=dtypes.complex128) else: mat = math_ops.cast(mat, dtype=dtypes.float64) mat_eigvals = sort_ops.sort(math_ops.cast( linalg_ops.self_adjoint_eigvals(mat), dtype=dtypes.float64), axis=-1) op_eigvals_v, mat_eigvals_v = sess.run([op_eigvals, mat_eigvals]) atol = self._atol[dtype] # pylint: disable=protected-access rtol = self._rtol[dtype] # pylint: disable=protected-access if dtype == dtypes.float32 or dtype == dtypes.complex64: atol = 2e-4 rtol = 2e-4 self.assertAllClose(op_eigvals_v, mat_eigvals_v, atol=atol, rtol=rtol)
def Test(self): np.random.seed(1) n = shape_[-1] batch_shape = shape_[:-2] np_dtype = dtype_.as_numpy_dtype a = np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) if dtype_.is_complex: a += 1j * np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) a += np.conj(a.T) a = np.tile(a, batch_shape + (1, 1)) if dtype_ in (dtypes_lib.float32, dtypes_lib.complex64): atol = 1e-4 else: atol = 1e-12 np_e, np_v = np.linalg.eigh(a) with self.test_session(): if compute_v_: tf_e, tf_v = linalg_ops.self_adjoint_eig(constant_op.constant(a)) # Check that V*diag(E)*V^T is close to A. a_ev = math_ops.matmul( math_ops.matmul(tf_v, array_ops.matrix_diag(tf_e)), tf_v, adjoint_b=True) self.assertAllClose(a_ev.eval(), a, atol=atol) # Compare to numpy.linalg.eigh. CompareEigenDecompositions(self, np_e, np_v, tf_e.eval(), tf_v.eval(), atol) else: tf_e = linalg_ops.self_adjoint_eigvals(constant_op.constant(a)) self.assertAllClose( np.sort(np_e, -1), np.sort(tf_e.eval(), -1), atol=atol)
def Test(self): np.random.seed(1) n = shape_[-1] batch_shape = shape_[:-2] a = np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(dtype_) a += np.conj(a.T) a = np.tile(a, batch_shape + (1, 1)) if dtype_ == np.float32 or dtype_ == np.complex64: atol = 1e-4 else: atol = 1e-12 for compute_v in False, True: np_e, np_v = np.linalg.eig(a) with self.test_session(): if compute_v: tf_e, tf_v = linalg_ops.self_adjoint_eig(constant_op.constant(a)) # Check that V*diag(E)*V^T is close to A. a_ev = math_ops.matmul( math_ops.matmul(tf_v, array_ops.matrix_diag(tf_e)), tf_v, adjoint_b=True) self.assertAllClose(a_ev.eval(), a, atol=atol) # Compare to numpy.linalg.eig. CompareEigenDecompositions(self, np_e, np_v, tf_e.eval(), tf_v.eval(), atol) else: tf_e = linalg_ops.self_adjoint_eigvals(constant_op.constant(a)) self.assertAllClose( np.sort(np_e, -1), np.sort(tf_e.eval(), -1), atol=atol)
def Test(self): np.random.seed(1) n = shape_[-1] batch_shape = shape_[:-2] np_dtype = dtype_.as_numpy_dtype a = np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) if dtype_.is_complex: a += 1j * np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) a += np.conj(a.T) a = np.tile(a, batch_shape + (1, 1)) if dtype_ in (dtypes_lib.float32, dtypes_lib.complex64): atol = 1e-4 else: atol = 1e-12 np_e, np_v = np.linalg.eigh(a) with self.session(use_gpu=True): if compute_v_: tf_e, tf_v = linalg_ops.self_adjoint_eig(constant_op.constant(a)) # Check that V*diag(E)*V^T is close to A. a_ev = math_ops.matmul( math_ops.matmul(tf_v, array_ops.matrix_diag(tf_e)), tf_v, adjoint_b=True) self.assertAllClose(self.evaluate(a_ev), a, atol=atol) # Compare to numpy.linalg.eigh. CompareEigenDecompositions(self, np_e, np_v, self.evaluate(tf_e), self.evaluate(tf_v), atol) else: tf_e = linalg_ops.self_adjoint_eigvals(constant_op.constant(a)) self.assertAllClose( np.sort(np_e, -1), np.sort(self.evaluate(tf_e), -1), atol=atol)
def Test(self): np.random.seed(1) n = shape_[-1] batch_shape = shape_[:-2] np_dtype = dtype_.as_numpy_dtype a = np.random.uniform(low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) if dtype_.is_complex: a += 1j * np.random.uniform(low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) a += np.conj(a.T) a = np.tile(a, batch_shape + (1, 1)) # Optimal stepsize for central difference is O(epsilon^{1/3}). epsilon = np.finfo(np_dtype).eps delta = 0.1 * epsilon**(1.0 / 3.0) # tolerance obtained by looking at actual differences using # np.linalg.norm(theoretical-numerical, np.inf) on -mavx build if dtype_ in (dtypes_lib.float32, dtypes_lib.complex64): tol = 1e-2 else: tol = 1e-7 with self.session(use_gpu=True): tf_a = constant_op.constant(a) if compute_v_: tf_e, tf_v = linalg_ops.self_adjoint_eig(tf_a) # (complex) Eigenvectors are only unique up to an arbitrary phase # We normalize the vectors such that the first component has phase 0. top_rows = tf_v[..., 0:1, :] if tf_a.dtype.is_complex: angle = -math_ops.angle(top_rows) phase = math_ops.complex(math_ops.cos(angle), math_ops.sin(angle)) else: phase = math_ops.sign(top_rows) tf_v *= phase outputs = [tf_e, tf_v] else: tf_e = linalg_ops.self_adjoint_eigvals(tf_a) outputs = [tf_e] for b in outputs: x_init = np.random.uniform(low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) if dtype_.is_complex: x_init += 1j * np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape( [n, n]).astype(np_dtype) x_init += np.conj(x_init.T) x_init = np.tile(x_init, batch_shape + (1, 1)) theoretical, numerical = gradient_checker.compute_gradient( tf_a, tf_a.get_shape().as_list(), b, b.get_shape().as_list(), x_init_value=x_init, delta=delta) self.assertAllClose(theoretical, numerical, atol=tol, rtol=tol)
def Test(self): np.random.seed(1) n = shape_[-1] batch_shape = shape_[:-2] np_dtype = dtype_.as_numpy_dtype a = np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) if dtype_.is_complex: a += 1j * np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) a += np.conj(a.T) a = np.tile(a, batch_shape + (1, 1)) # Optimal stepsize for central difference is O(epsilon^{1/3}). epsilon = np.finfo(np_dtype).eps delta = 0.1 * epsilon**(1.0 / 3.0) # tolerance obtained by looking at actual differences using # np.linalg.norm(theoretical-numerical, np.inf) on -mavx build if dtype_ in (dtypes_lib.float32, dtypes_lib.complex64): tol = 1e-2 else: tol = 1e-7 with self.session(use_gpu=True): tf_a = constant_op.constant(a) if compute_v_: tf_e, tf_v = linalg_ops.self_adjoint_eig(tf_a) # (complex) Eigenvectors are only unique up to an arbitrary phase # We normalize the vectors such that the first component has phase 0. top_rows = tf_v[..., 0:1, :] if tf_a.dtype.is_complex: angle = -math_ops.angle(top_rows) phase = math_ops.complex(math_ops.cos(angle), math_ops.sin(angle)) else: phase = math_ops.sign(top_rows) tf_v *= phase outputs = [tf_e, tf_v] else: tf_e = linalg_ops.self_adjoint_eigvals(tf_a) outputs = [tf_e] for b in outputs: x_init = np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) if dtype_.is_complex: x_init += 1j * np.random.uniform( low=-1.0, high=1.0, size=n * n).reshape([n, n]).astype(np_dtype) x_init += np.conj(x_init.T) x_init = np.tile(x_init, batch_shape + (1, 1)) theoretical, numerical = gradient_checker.compute_gradient( tf_a, tf_a.get_shape().as_list(), b, b.get_shape().as_list(), x_init_value=x_init, delta=delta) self.assertAllClose(theoretical, numerical, atol=tol, rtol=tol)
def testConcurrentExecutesWithoutError(self): all_ops = [] with self.session(use_gpu=True) as sess: for compute_v_ in True, False: matrix1 = random_ops.random_normal([5, 5], seed=42) matrix2 = random_ops.random_normal([5, 5], seed=42) if compute_v_: e1, v1 = linalg_ops.self_adjoint_eig(matrix1) e2, v2 = linalg_ops.self_adjoint_eig(matrix2) all_ops += [e1, v1, e2, v2] else: e1 = linalg_ops.self_adjoint_eigvals(matrix1) e2 = linalg_ops.self_adjoint_eigvals(matrix2) all_ops += [e1, e2] val = self.evaluate(all_ops) self.assertAllEqual(val[0], val[2]) # The algorithm is slightly different for compute_v being True and False, # so require approximate equality only here. self.assertAllClose(val[2], val[4]) self.assertAllEqual(val[4], val[5]) self.assertAllEqual(val[1], val[3])
def testConcurrentExecutesWithoutError(self): all_ops = [] with self.session(use_gpu=True) as sess: for compute_v_ in True, False: matrix1 = random_ops.random_normal([5, 5], seed=42) matrix2 = random_ops.random_normal([5, 5], seed=42) if compute_v_: e1, v1 = linalg_ops.self_adjoint_eig(matrix1) e2, v2 = linalg_ops.self_adjoint_eig(matrix2) all_ops += [e1, v1, e2, v2] else: e1 = linalg_ops.self_adjoint_eigvals(matrix1) e2 = linalg_ops.self_adjoint_eigvals(matrix2) all_ops += [e1, e2] val = sess.run(all_ops) self.assertAllEqual(val[0], val[2]) # The algorithm is slightly different for compute_v being True and False, # so require approximate equality only here. self.assertAllClose(val[2], val[4]) self.assertAllEqual(val[4], val[5]) self.assertAllEqual(val[1], val[3])
def loop_fn(i): return (linalg_ops.self_adjoint_eig(array_ops.gather(x, i)), linalg_ops.self_adjoint_eigvals(array_ops.gather(x, i)))
def _eigvals(self): return linalg_ops.self_adjoint_eigvals(self.to_dense())