(self, dtype, shape)
| 42 | return np.matmul(u * s[..., None, :], np.swapaxes(v, -1, -2)) |
| 43 | |
| 44 | def _testSvdCorrectness(self, dtype, shape): |
| 45 | np.random.seed(1) |
| 46 | x_np = np.random.uniform(low=-1.0, high=1.0, size=shape).astype(dtype) |
| 47 | m, n = shape[-2], shape[-1] |
| 48 | _, s_np, _ = np.linalg.svd(x_np) |
| 49 | with self.session() as sess: |
| 50 | x_tf = array_ops.placeholder(dtype) |
| 51 | with self.test_scope(): |
| 52 | s, u, v = linalg_ops.svd(x_tf, full_matrices=True) |
| 53 | s_val, u_val, v_val = sess.run([s, u, v], feed_dict={x_tf: x_np}) |
| 54 | u_diff = np.matmul(u_val, np.swapaxes(u_val, -1, -2)) - np.eye(m) |
| 55 | v_diff = np.matmul(v_val, np.swapaxes(v_val, -1, -2)) - np.eye(n) |
| 56 | # Check u_val and v_val are orthogonal matrices. |
| 57 | self.assertLess(np.linalg.norm(u_diff), 1e-2) |
| 58 | self.assertLess(np.linalg.norm(v_diff), 1e-2) |
| 59 | # Check that the singular values are correct, i.e., close to the ones from |
| 60 | # numpy.lingal.svd. |
| 61 | self.assertLess(np.linalg.norm(s_val - s_np), 1e-2) |
| 62 | # The tolerance is set based on our tests on numpy's svd. As our tests |
| 63 | # have batch dimensions and all our operations are on float32, we set the |
| 64 | # tolerance a bit larger. Numpy's svd calls LAPACK's svd, which operates |
| 65 | # on double precision. |
| 66 | self.assertLess( |
| 67 | np.linalg.norm(self._compute_usvt(s_val, u_val, v_val) - x_np), 2e-2) |
| 68 | |
| 69 | # Check behavior with compute_uv=False. We expect to still see 3 outputs, |
| 70 | # with a sentinel scalar 0 in the last two outputs. |
| 71 | with self.test_scope(): |
| 72 | no_uv_s, no_uv_u, no_uv_v = gen_linalg_ops.svd( |
| 73 | x_tf, full_matrices=True, compute_uv=False) |
| 74 | no_uv_s_val, no_uv_u_val, no_uv_v_val = sess.run( |
| 75 | [no_uv_s, no_uv_u, no_uv_v], feed_dict={x_tf: x_np}) |
| 76 | self.assertAllClose(no_uv_s_val, s_val, atol=1e-4, rtol=1e-4) |
| 77 | self.assertEqual(no_uv_u_val, 0.0) |
| 78 | self.assertEqual(no_uv_v_val, 0.0) |
| 79 | |
| 80 | SIZES = [1, 2, 5, 10, 32, 64] |
| 81 | DTYPES = [np.float32] |
no test coverage detected