Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/ops/linalg_ops.py: 31%

176 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14# ============================================================================== 

15"""Operations for linear algebra.""" 

16 

17import numpy as np 

18 

19from tensorflow.python.framework import dtypes 

20from tensorflow.python.framework import ops 

21from tensorflow.python.ops import array_ops 

22from tensorflow.python.ops import cond 

23from tensorflow.python.ops import gen_array_ops 

24from tensorflow.python.ops import gen_linalg_ops 

25from tensorflow.python.ops import linalg_ops_impl 

26from tensorflow.python.ops import map_fn 

27from tensorflow.python.ops import math_ops 

28# pylint: disable=wildcard-import 

29from tensorflow.python.ops.gen_linalg_ops import * 

30# pylint: enable=wildcard-import 

31from tensorflow.python.util import deprecation 

32from tensorflow.python.util import dispatch 

33from tensorflow.python.util.tf_export import tf_export 

34 

35# Names below are lower_case. 

36# pylint: disable=invalid-name 

37 

38 

39def _RegularizedGramianCholesky(matrix, l2_regularizer, first_kind): 

40 r"""Computes Cholesky factorization of regularized gramian matrix. 

41 

42 Below we will use the following notation for each pair of matrix and 

43 right-hand sides in the batch: 

44 

45 `matrix`=\\(A \in \Re^{m \times n}\\), 

46 `output`=\\(C \in \Re^{\min(m, n) \times \min(m,n)}\\), 

47 `l2_regularizer`=\\(\lambda\\). 

48 

49 If `first_kind` is True, returns the Cholesky factorization \\(L\\) such that 

50 \\(L L^H = A^H A + \lambda I\\). 

51 If `first_kind` is False, returns the Cholesky factorization \\(L\\) such that 

52 \\(L L^H = A A^H + \lambda I\\). 

53 

54 Args: 

55 matrix: `Tensor` of shape `[..., M, N]`. 

56 l2_regularizer: 0-D `double` `Tensor`. Ignored if `fast=False`. 

57 first_kind: bool. Controls what gramian matrix to factor. 

58 Returns: 

59 output: `Tensor` of shape `[..., min(M,N), min(M,N)]` whose inner-most 2 

60 dimensions contain the Cholesky factors \\(L\\) described above. 

61 """ 

62 

63 gramian = math_ops.matmul( 

64 matrix, matrix, adjoint_a=first_kind, adjoint_b=not first_kind) 

65 if isinstance(l2_regularizer, ops.Tensor) or l2_regularizer != 0: 

66 matrix_shape = array_ops.shape(matrix) 

67 batch_shape = matrix_shape[:-2] 

68 if first_kind: 

69 small_dim = matrix_shape[-1] 

70 else: 

71 small_dim = matrix_shape[-2] 

72 identity = eye(small_dim, batch_shape=batch_shape, dtype=matrix.dtype) 

73 small_dim_static = matrix.shape[-1 if first_kind else -2] 

74 identity.set_shape( 

75 matrix.shape[:-2].concatenate([small_dim_static, small_dim_static])) 

76 gramian += l2_regularizer * identity 

77 return gen_linalg_ops.cholesky(gramian) 

78 

79 

80@tf_export( 

81 'linalg.triangular_solve', 

82 v1=['linalg.triangular_solve', 'matrix_triangular_solve']) 

83@dispatch.add_dispatch_support 

84def matrix_triangular_solve(matrix, rhs, lower=True, adjoint=False, name=None): 

85 """Solve systems of linear equations with upper or lower triangular matrices. 

86 

87 `matrix` is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form 

88 square matrices. If `lower` is `True` then the strictly upper triangular part 

89 of each inner-most matrix is assumed to be zero and not accessed. If `lower` 

90 is `False` then the strictly lower triangular part of each inner-most matrix 

91 is assumed to be zero and not accessed. `rhs` is a tensor of shape 

92 `[..., M, N]`. 

93 

94 The output is a tensor of shape `[..., M, N]`. If `adjoint` is `True` then the 

95 innermost matrices in output satisfy matrix equations ` 

96 sum_k matrix[..., i, k] * output[..., k, j] = rhs[..., i, j]`. 

97 If `adjoint` is `False` then the 

98 innermost matrices in output satisfy matrix equations 

99 `sum_k adjoint(matrix[..., i, k]) * output[..., k, j] = rhs[..., i, j]`. 

100 

101 Example: 

102 

103 >>> a = tf.constant([[3, 0, 0, 0], 

104 ... [2, 1, 0, 0], 

105 ... [1, 0, 1, 0], 

106 ... [1, 1, 1, 1]], dtype=tf.float32) 

107 

108 >>> b = tf.constant([[4], [2], [4], [2]], dtype=tf.float32) 

109 >>> x = tf.linalg.triangular_solve(a, b, lower=True) 

110 >>> x 

111 <tf.Tensor: shape=(4, 1), dtype=float32, numpy= 

112 array([[ 1.3333334 ], 

113 [-0.66666675], 

114 [ 2.6666665 ], 

115 [-1.3333331 ]], dtype=float32)> 

116 >>> tf.matmul(a, x) 

117 <tf.Tensor: shape=(4, 1), dtype=float32, numpy= 

118 array([[4.], 

119 [2.], 

120 [4.], 

121 [2.]], dtype=float32)> 

122 

123 Args: 

124 matrix: A `Tensor`. Must be one of the following types: `float64`, 

125 `float32`, `half`, `complex64`, `complex128`. Shape is `[..., M, M]`. 

126 rhs: A `Tensor`. Must have the same type as `matrix`. Shape is `[..., M, 

127 N]`. 

128 lower: An optional `bool`. Defaults to `True`. Boolean indicating whether 

129 the innermost matrices in matrix are lower or upper triangular. 

130 adjoint: An optional `bool`. Defaults to `False`. Boolean indicating whether 

131 to solve with matrix or its (block-wise) adjoint. 

132 name: A name for the operation (optional). 

133 

134 Returns: 

135 A `Tensor`. Has the same type as matrix, and shape is `[..., M, N]`. 

136 

137 """ 

138 with ops.name_scope(name, 'triangular_solve', [matrix, rhs]): 

139 return gen_linalg_ops.matrix_triangular_solve( 

140 matrix, rhs, lower=lower, adjoint=adjoint) 

141 

142 

143@tf_export( 

144 'linalg.cholesky_solve', v1=['linalg.cholesky_solve', 'cholesky_solve']) 

145@dispatch.add_dispatch_support 

146@deprecation.deprecated_endpoints('cholesky_solve') 

147def cholesky_solve(chol, rhs, name=None): 

148 """Solves systems of linear eqns `A X = RHS`, given Cholesky factorizations. 

149 

150 Specifically, returns `X` from `A X = RHS`, where `A = L L^T`, `L` is the 

151 `chol` arg and `RHS` is the `rhs` arg. 

152 

153 ```python 

154 # Solve 10 separate 2x2 linear systems: 

155 A = ... # shape 10 x 2 x 2 

156 RHS = ... # shape 10 x 2 x 1 

157 chol = tf.linalg.cholesky(A) # shape 10 x 2 x 2 

158 X = tf.linalg.cholesky_solve(chol, RHS) # shape 10 x 2 x 1 

159 # tf.matmul(A, X) ~ RHS 

160 X[3, :, 0] # Solution to the linear system A[3, :, :] x = RHS[3, :, 0] 

161 

162 # Solve five linear systems (K = 5) for every member of the length 10 batch. 

163 A = ... # shape 10 x 2 x 2 

164 RHS = ... # shape 10 x 2 x 5 

165 ... 

166 X[3, :, 2] # Solution to the linear system A[3, :, :] x = RHS[3, :, 2] 

167 ``` 

168 

169 Args: 

170 chol: A `Tensor`. Must be `float32` or `float64`, shape is `[..., M, M]`. 

171 Cholesky factorization of `A`, e.g. `chol = tf.linalg.cholesky(A)`. 

172 For that reason, only the lower triangular parts (including the diagonal) 

173 of the last two dimensions of `chol` are used. The strictly upper part is 

174 assumed to be zero and not accessed. 

175 rhs: A `Tensor`, same type as `chol`, shape is `[..., M, K]`. 

176 name: A name to give this `Op`. Defaults to `cholesky_solve`. 

177 

178 Returns: 

179 Solution to `A x = rhs`, shape `[..., M, K]`. 

180 """ 

181 # To solve C C^* x = rhs, we 

182 # 1. Solve C y = rhs for y, thus y = C^* x 

183 # 2. Solve C^* x = y for x 

184 with ops.name_scope(name, 'cholesky_solve', [chol, rhs]): 

185 y = gen_linalg_ops.matrix_triangular_solve( 

186 chol, rhs, adjoint=False, lower=True) 

187 x = gen_linalg_ops.matrix_triangular_solve( 

188 chol, y, adjoint=True, lower=True) 

189 return x 

190 

191 

192@tf_export('eye', 'linalg.eye') 

193@dispatch.add_dispatch_support 

194def eye(num_rows, 

195 num_columns=None, 

196 batch_shape=None, 

197 dtype=dtypes.float32, 

198 name=None): 

199 """Construct an identity matrix, or a batch of matrices. 

200 

201 See also `tf.ones`, `tf.zeros`, `tf.fill`, `tf.one_hot`. 

202 

203 ```python 

204 # Construct one identity matrix. 

205 tf.eye(2) 

206 ==> [[1., 0.], 

207 [0., 1.]] 

208 

209 # Construct a batch of 3 identity matrices, each 2 x 2. 

210 # batch_identity[i, :, :] is a 2 x 2 identity matrix, i = 0, 1, 2. 

211 batch_identity = tf.eye(2, batch_shape=[3]) 

212 

213 # Construct one 2 x 3 "identity" matrix 

214 tf.eye(2, num_columns=3) 

215 ==> [[ 1., 0., 0.], 

216 [ 0., 1., 0.]] 

217 ``` 

218 

219 Args: 

220 num_rows: Non-negative `int32` scalar `Tensor` giving the number of rows 

221 in each batch matrix. 

222 num_columns: Optional non-negative `int32` scalar `Tensor` giving the number 

223 of columns in each batch matrix. Defaults to `num_rows`. 

224 batch_shape: A list or tuple of Python integers or a 1-D `int32` `Tensor`. 

225 If provided, the returned `Tensor` will have leading batch dimensions of 

226 this shape. 

227 dtype: The type of an element in the resulting `Tensor` 

228 name: A name for this `Op`. Defaults to "eye". 

229 

230 Returns: 

231 A `Tensor` of shape `batch_shape + [num_rows, num_columns]` 

232 """ 

233 return linalg_ops_impl.eye(num_rows, 

234 num_columns=num_columns, 

235 batch_shape=batch_shape, 

236 dtype=dtype, 

237 name=name) 

238 

239 

240@tf_export('linalg.lstsq', v1=['linalg.lstsq', 'matrix_solve_ls']) 

241@dispatch.add_dispatch_support 

242@deprecation.deprecated_endpoints('matrix_solve_ls') 

243def matrix_solve_ls(matrix, rhs, l2_regularizer=0.0, fast=True, name=None): 

244 r"""Solves one or more linear least-squares problems. 

245 

246 `matrix` is a tensor of shape `[..., M, N]` whose inner-most 2 dimensions 

247 form `M`-by-`N` matrices. Rhs is a tensor of shape `[..., M, K]` whose 

248 inner-most 2 dimensions form `M`-by-`K` matrices. The computed output is a 

249 `Tensor` of shape `[..., N, K]` whose inner-most 2 dimensions form `M`-by-`K` 

250 matrices that solve the equations 

251 `matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]` in the least squares 

252 sense. 

253 

254 Below we will use the following notation for each pair of matrix and 

255 right-hand sides in the batch: 

256 

257 `matrix`=\\(A \in \Re^{m \times n}\\), 

258 `rhs`=\\(B \in \Re^{m \times k}\\), 

259 `output`=\\(X \in \Re^{n \times k}\\), 

260 `l2_regularizer`=\\(\lambda\\). 

261 

262 If `fast` is `True`, then the solution is computed by solving the normal 

263 equations using Cholesky decomposition. Specifically, if \\(m \ge n\\) then 

264 \\(X = (A^T A + \lambda I)^{-1} A^T B\\), which solves the least-squares 

265 problem \\(X = \mathrm{argmin}_{Z \in \Re^{n \times k}} ||A Z - B||_F^2 + 

266 \lambda ||Z||_F^2\\). If \\(m \lt n\\) then `output` is computed as 

267 \\(X = A^T (A A^T + \lambda I)^{-1} B\\), which (for \\(\lambda = 0\\)) is 

268 the minimum-norm solution to the under-determined linear system, i.e. 

269 \\(X = \mathrm{argmin}_{Z \in \Re^{n \times k}} ||Z||_F^2 \\), subject to 

270 \\(A Z = B\\). Notice that the fast path is only numerically stable when 

271 \\(A\\) is numerically full rank and has a condition number 

272 \\(\mathrm{cond}(A) \lt \frac{1}{\sqrt{\epsilon_{mach}}}\\) or\\(\lambda\\) 

273 is sufficiently large. 

274 

275 If `fast` is `False` an algorithm based on the numerically robust complete 

276 orthogonal decomposition is used. This computes the minimum-norm 

277 least-squares solution, even when \\(A\\) is rank deficient. This path is 

278 typically 6-7 times slower than the fast path. If `fast` is `False` then 

279 `l2_regularizer` is ignored. 

280 

281 Args: 

282 matrix: `Tensor` of shape `[..., M, N]`. 

283 rhs: `Tensor` of shape `[..., M, K]`. 

284 l2_regularizer: 0-D `double` `Tensor`. Ignored if `fast=False`. 

285 fast: bool. Defaults to `True`. 

286 name: string, optional name of the operation. 

287 

288 Returns: 

289 output: `Tensor` of shape `[..., N, K]` whose inner-most 2 dimensions form 

290 `M`-by-`K` matrices that solve the equations 

291 `matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]` in the least 

292 squares sense. 

293 

294 Raises: 

295 NotImplementedError: linalg.lstsq is currently disabled for complex128 

296 and l2_regularizer != 0 due to poor accuracy. 

297 """ 

298 

299 # pylint: disable=long-lambda 

300 def _use_composite_impl(fast, tensor_shape): 

301 """Determines whether to use the composite or specialized CPU kernel. 

302 

303 When the total size of the tensor is larger than the cache size and the 

304 batch size is large compared to the smallest matrix dimension, then the 

305 composite implementation is inefficient since it has to read the entire 

306 tensor from memory multiple times. In this case we fall back to the 

307 original CPU kernel, which does all the computational steps on each 

308 matrix separately. 

309 

310 Only fast mode is supported by the composite impl, so `False` is returned 

311 if `fast` is `False`. 

312 

313 Args: 

314 fast: bool indicating if fast mode in the solver was requested. 

315 tensor_shape: The shape of the tensor. 

316 

317 Returns: 

318 True if the composite impl should be used. False otherwise. 

319 """ 

320 if fast is False: 

321 return False 

322 batch_shape = tensor_shape[:-2] 

323 matrix_shape = tensor_shape[-2:] 

324 if not tensor_shape.is_fully_defined(): 

325 return True 

326 tensor_size = tensor_shape.num_elements() * matrix.dtype.size 

327 is_io_bound = batch_shape.num_elements() > np.min(matrix_shape) 

328 L2_CACHE_SIZE_GUESSTIMATE = 256000 

329 if tensor_size > L2_CACHE_SIZE_GUESSTIMATE and is_io_bound: 

330 return False 

331 else: 

332 return True 

333 

334 def _overdetermined(matrix, rhs, l2_regularizer): 

335 """Computes (A^H*A + l2_regularizer)^{-1} * A^H * rhs.""" 

336 chol = _RegularizedGramianCholesky( 

337 matrix, l2_regularizer=l2_regularizer, first_kind=True) 

338 return cholesky_solve(chol, math_ops.matmul(matrix, rhs, adjoint_a=True)) 

339 

340 def _underdetermined(matrix, rhs, l2_regularizer): 

341 """Computes A^H * (A*A^H + l2_regularizer)^{-1} * rhs.""" 

342 chol = _RegularizedGramianCholesky( 

343 matrix, l2_regularizer=l2_regularizer, first_kind=False) 

344 return math_ops.matmul(matrix, cholesky_solve(chol, rhs), adjoint_a=True) 

345 

346 def _composite_impl(matrix, rhs, l2_regularizer): 

347 """Composite implementation of matrix_solve_ls that supports GPU.""" 

348 with ops.name_scope(name, 'matrix_solve_ls', [matrix, rhs, l2_regularizer]): 

349 matrix_shape = matrix.get_shape()[-2:] 

350 if matrix_shape.is_fully_defined(): 

351 if matrix_shape[-2] >= matrix_shape[-1]: 

352 return _overdetermined(matrix, rhs, l2_regularizer) 

353 else: 

354 return _underdetermined(matrix, rhs, l2_regularizer) 

355 else: 

356 # We have to defer determining the shape to runtime and use 

357 # conditional execution of the appropriate graph. 

358 matrix_shape = array_ops.shape(matrix)[-2:] 

359 return cond.cond( 

360 matrix_shape[-2] >= matrix_shape[-1], 

361 lambda: _overdetermined(matrix, rhs, l2_regularizer), 

362 lambda: _underdetermined(matrix, rhs, l2_regularizer)) 

363 

364 matrix = ops.convert_to_tensor(matrix, name='matrix') 

365 if matrix.dtype == dtypes.complex128 and l2_regularizer != 0: 

366 # TODO(rmlarsen): Investigate and fix accuracy bug. 

367 raise NotImplementedError('matrix_solve_ls is currently disabled for ' 

368 'complex128 and l2_regularizer != 0 due to ' 

369 'poor accuracy.') 

370 tensor_shape = matrix.get_shape() 

371 if _use_composite_impl(fast, tensor_shape): 

372 return _composite_impl(matrix, rhs, l2_regularizer) 

373 else: 

374 return gen_linalg_ops.matrix_solve_ls( 

375 matrix, rhs, l2_regularizer, fast=fast, name=name) 

376 

377 

378@tf_export('linalg.eig', 'eig', v1=[]) 

379@dispatch.add_dispatch_support 

380def eig(tensor, name=None): 

381 """Computes the eigen decomposition of a batch of matrices. 

382 

383 The eigenvalues 

384 and eigenvectors for a non-Hermitian matrix in general are complex. The 

385 eigenvectors are not guaranteed to be linearly independent. 

386 

387 Computes the eigenvalues and right eigenvectors of the innermost 

388 N-by-N matrices in `tensor` such that 

389 `tensor[...,:,:] * v[..., :,i] = e[..., i] * v[...,:,i]`, for i=0...N-1. 

390 

391 Args: 

392 tensor: `Tensor` of shape `[..., N, N]`. Only the lower triangular part of 

393 each inner inner matrix is referenced. 

394 name: string, optional name of the operation. 

395 

396 Returns: 

397 e: Eigenvalues. Shape is `[..., N]`. The eigenvalues are not necessarily 

398 ordered. 

399 v: Eigenvectors. Shape is `[..., N, N]`. The columns of the inner most 

400 matrices contain eigenvectors of the corresponding matrices in `tensor` 

401 """ 

402 if tensor.dtype == dtypes.float32 or tensor.dtype == dtypes.complex64: 

403 out_dtype = dtypes.complex64 

404 elif tensor.dtype == dtypes.float64 or tensor.dtype == dtypes.complex128: 

405 out_dtype = dtypes.complex128 

406 e, v = gen_linalg_ops.eig(tensor, Tout=out_dtype, compute_v=True, name=name) 

407 return e, v 

408 

409 

410@tf_export('linalg.eigvals', 'eigvals', v1=[]) 

411@dispatch.add_dispatch_support 

412def eigvals(tensor, name=None): 

413 """Computes the eigenvalues of one or more matrices. 

414 

415 Note: If your program backpropagates through this function, you should replace 

416 it with a call to tf.linalg.eig (possibly ignoring the second output) to 

417 avoid computing the eigen decomposition twice. This is because the 

418 eigenvectors are used to compute the gradient w.r.t. the eigenvalues. See 

419 _SelfAdjointEigV2Grad in linalg_grad.py. 

420 

421 Args: 

422 tensor: `Tensor` of shape `[..., N, N]`. 

423 name: string, optional name of the operation. 

424 

425 Returns: 

426 e: Eigenvalues. Shape is `[..., N]`. The vector `e[..., :]` contains the `N` 

427 eigenvalues of `tensor[..., :, :]`. 

428 """ 

429 if tensor.dtype == dtypes.float32 or tensor.dtype == dtypes.complex64: 

430 out_dtype = dtypes.complex64 

431 elif tensor.dtype == dtypes.float64 or tensor.dtype == dtypes.complex128: 

432 out_dtype = dtypes.complex128 

433 e, _ = gen_linalg_ops.eig(tensor, Tout=out_dtype, compute_v=False, name=name) 

434 return e 

435 

436 

437@tf_export('linalg.eigh', v1=['linalg.eigh', 'self_adjoint_eig']) 

438@dispatch.add_dispatch_support 

439@deprecation.deprecated_endpoints('self_adjoint_eig') 

440def self_adjoint_eig(tensor, name=None): 

441 """Computes the eigen decomposition of a batch of self-adjoint matrices. 

442 

443 Computes the eigenvalues and eigenvectors of the innermost N-by-N matrices 

444 in `tensor` such that 

445 `tensor[...,:,:] * v[..., :,i] = e[..., i] * v[...,:,i]`, for i=0...N-1. 

446 

447 Args: 

448 tensor: `Tensor` of shape `[..., N, N]`. Only the lower triangular part of 

449 each inner inner matrix is referenced. 

450 name: string, optional name of the operation. 

451 

452 Returns: 

453 e: Eigenvalues. Shape is `[..., N]`. Sorted in non-decreasing order. 

454 v: Eigenvectors. Shape is `[..., N, N]`. The columns of the inner most 

455 matrices contain eigenvectors of the corresponding matrices in `tensor` 

456 """ 

457 e, v = gen_linalg_ops.self_adjoint_eig_v2(tensor, compute_v=True, name=name) 

458 return e, v 

459 

460 

461@tf_export('linalg.eigvalsh', v1=['linalg.eigvalsh', 'self_adjoint_eigvals']) 

462@dispatch.add_dispatch_support 

463@deprecation.deprecated_endpoints('self_adjoint_eigvals') 

464def self_adjoint_eigvals(tensor, name=None): 

465 """Computes the eigenvalues of one or more self-adjoint matrices. 

466 

467 Note: If your program backpropagates through this function, you should replace 

468 it with a call to tf.linalg.eigh (possibly ignoring the second output) to 

469 avoid computing the eigen decomposition twice. This is because the 

470 eigenvectors are used to compute the gradient w.r.t. the eigenvalues. See 

471 _SelfAdjointEigV2Grad in linalg_grad.py. 

472 

473 Args: 

474 tensor: `Tensor` of shape `[..., N, N]`. 

475 name: string, optional name of the operation. 

476 

477 Returns: 

478 e: Eigenvalues. Shape is `[..., N]`. The vector `e[..., :]` contains the `N` 

479 eigenvalues of `tensor[..., :, :]`. 

480 """ 

481 e, _ = gen_linalg_ops.self_adjoint_eig_v2(tensor, compute_v=False, name=name) 

482 return e 

483 

484 

485@tf_export('linalg.svd', v1=['linalg.svd', 'svd']) 

486@dispatch.add_dispatch_support 

487@deprecation.deprecated_endpoints('svd') 

488def svd(tensor, full_matrices=False, compute_uv=True, name=None): 

489 r"""Computes the singular value decompositions of one or more matrices. 

490 

491 Computes the SVD of each inner matrix in `tensor` such that 

492 `tensor[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * 

493 transpose(conj(v[..., :, :]))` 

494 

495 ```python 

496 # a is a tensor. 

497 # s is a tensor of singular values. 

498 # u is a tensor of left singular vectors. 

499 # v is a tensor of right singular vectors. 

500 s, u, v = svd(a) 

501 s = svd(a, compute_uv=False) 

502 ``` 

503 

504 Args: 

505 tensor: `Tensor` of shape `[..., M, N]`. Let `P` be the minimum of `M` and 

506 `N`. 

507 full_matrices: If true, compute full-sized `u` and `v`. If false 

508 (the default), compute only the leading `P` singular vectors. 

509 Ignored if `compute_uv` is `False`. 

510 compute_uv: If `True` then left and right singular vectors will be 

511 computed and returned in `u` and `v`, respectively. Otherwise, only the 

512 singular values will be computed, which can be significantly faster. 

513 name: string, optional name of the operation. 

514 

515 Returns: 

516 s: Singular values. Shape is `[..., P]`. The values are sorted in reverse 

517 order of magnitude, so s[..., 0] is the largest value, s[..., 1] is the 

518 second largest, etc. 

519 u: Left singular vectors. If `full_matrices` is `False` (default) then 

520 shape is `[..., M, P]`; if `full_matrices` is `True` then shape is 

521 `[..., M, M]`. Not returned if `compute_uv` is `False`. 

522 v: Right singular vectors. If `full_matrices` is `False` (default) then 

523 shape is `[..., N, P]`. If `full_matrices` is `True` then shape is 

524 `[..., N, N]`. Not returned if `compute_uv` is `False`. 

525 

526 @compatibility(numpy) 

527 Mostly equivalent to numpy.linalg.svd, except that 

528 * The order of output arguments here is `s`, `u`, `v` when `compute_uv` is 

529 `True`, as opposed to `u`, `s`, `v` for numpy.linalg.svd. 

530 * full_matrices is `False` by default as opposed to `True` for 

531 numpy.linalg.svd. 

532 * tf.linalg.svd uses the standard definition of the SVD 

533 \\(A = U \Sigma V^H\\), such that the left singular vectors of `a` are 

534 the columns of `u`, while the right singular vectors of `a` are the 

535 columns of `v`. On the other hand, numpy.linalg.svd returns the adjoint 

536 \\(V^H\\) as the third output argument. 

537 ```python 

538 import tensorflow as tf 

539 import numpy as np 

540 s, u, v = tf.linalg.svd(a) 

541 tf_a_approx = tf.matmul(u, tf.matmul(tf.linalg.diag(s), v, adjoint_b=True)) 

542 u, s, v_adj = np.linalg.svd(a, full_matrices=False) 

543 np_a_approx = np.dot(u, np.dot(np.diag(s), v_adj)) 

544 # tf_a_approx and np_a_approx should be numerically close. 

545 ``` 

546 @end_compatibility 

547 """ 

548 s, u, v = gen_linalg_ops.svd( 

549 tensor, compute_uv=compute_uv, full_matrices=full_matrices, name=name) 

550 if compute_uv: 

551 return math_ops.real(s), u, v 

552 else: 

553 return math_ops.real(s) 

554 

555 

556# pylint: disable=redefined-builtin 

557@tf_export('norm', 'linalg.norm', v1=[]) 

558@dispatch.add_dispatch_support 

559def norm_v2(tensor, 

560 ord='euclidean', 

561 axis=None, 

562 keepdims=None, 

563 name=None): 

564 r"""Computes the norm of vectors, matrices, and tensors. 

565 

566 This function can compute several different vector norms (the 1-norm, the 

567 Euclidean or 2-norm, the inf-norm, and in general the p-norm for p > 0) and 

568 matrix norms (Frobenius, 1-norm, 2-norm and inf-norm). 

569 

570 Args: 

571 tensor: `Tensor` of types `float32`, `float64`, `complex64`, `complex128` 

572 ord: Order of the norm. Supported values are `'fro'`, `'euclidean'`, 

573 `1`, `2`, `np.inf` and any positive real number yielding the corresponding 

574 p-norm. Default is `'euclidean'` which is equivalent to Frobenius norm if 

575 `tensor` is a matrix and equivalent to 2-norm for vectors. 

576 Some restrictions apply: 

577 a) The Frobenius norm `'fro'` is not defined for vectors, 

578 b) If axis is a 2-tuple (matrix norm), only `'euclidean'`, '`fro'`, `1`, 

579 `2`, `np.inf` are supported. 

580 See the description of `axis` on how to compute norms for a batch of 

581 vectors or matrices stored in a tensor. 

582 axis: If `axis` is `None` (the default), the input is considered a vector 

583 and a single vector norm is computed over the entire set of values in the 

584 tensor, i.e. `norm(tensor, ord=ord)` is equivalent to 

585 `norm(reshape(tensor, [-1]), ord=ord)`. 

586 If `axis` is a Python integer, the input is considered a batch of vectors, 

587 and `axis` determines the axis in `tensor` over which to compute vector 

588 norms. 

589 If `axis` is a 2-tuple of Python integers it is considered a batch of 

590 matrices and `axis` determines the axes in `tensor` over which to compute 

591 a matrix norm. 

592 Negative indices are supported. Example: If you are passing a tensor that 

593 can be either a matrix or a batch of matrices at runtime, pass 

594 `axis=[-2,-1]` instead of `axis=None` to make sure that matrix norms are 

595 computed. 

596 keepdims: If True, the axis indicated in `axis` are kept with size 1. 

597 Otherwise, the dimensions in `axis` are removed from the output shape. 

598 name: The name of the op. 

599 

600 Returns: 

601 output: A `Tensor` of the same type as tensor, containing the vector or 

602 matrix norms. If `keepdims` is True then the rank of output is equal to 

603 the rank of `tensor`. Otherwise, if `axis` is none the output is a scalar, 

604 if `axis` is an integer, the rank of `output` is one less than the rank 

605 of `tensor`, if `axis` is a 2-tuple the rank of `output` is two less 

606 than the rank of `tensor`. 

607 

608 Raises: 

609 ValueError: If `ord` or `axis` is invalid. 

610 

611 @compatibility(numpy) 

612 Mostly equivalent to numpy.linalg.norm. 

613 Not supported: ord <= 0, 2-norm for matrices, nuclear norm. 

614 Other differences: 

615 a) If axis is `None`, treats the flattened `tensor` as a vector 

616 regardless of rank. 

617 b) Explicitly supports 'euclidean' norm as the default, including for 

618 higher order tensors. 

619 @end_compatibility 

620 """ 

621 return norm(tensor=tensor, 

622 ord=ord, 

623 axis=axis, 

624 keepdims=keepdims, 

625 name=name) 

626 

627 

628# pylint: disable=redefined-builtin 

629@tf_export(v1=['norm', 'linalg.norm']) 

630@dispatch.add_dispatch_support 

631@deprecation.deprecated_args( 

632 None, 'keep_dims is deprecated, use keepdims instead', 'keep_dims') 

633def norm(tensor, 

634 ord='euclidean', 

635 axis=None, 

636 keepdims=None, 

637 name=None, 

638 keep_dims=None): 

639 r"""Computes the norm of vectors, matrices, and tensors. 

640 

641 This function can compute several different vector norms (the 1-norm, the 

642 Euclidean or 2-norm, the inf-norm, and in general the p-norm for p > 0) and 

643 matrix norms (Frobenius, 1-norm, 2-norm and inf-norm). 

644 

645 Args: 

646 tensor: `Tensor` of types `float32`, `float64`, `complex64`, `complex128` 

647 ord: Order of the norm. Supported values are 'fro', 'euclidean', 

648 `1`, `2`, `np.inf` and any positive real number yielding the corresponding 

649 p-norm. Default is 'euclidean' which is equivalent to Frobenius norm if 

650 `tensor` is a matrix and equivalent to 2-norm for vectors. 

651 Some restrictions apply: 

652 a) The Frobenius norm `fro` is not defined for vectors, 

653 b) If axis is a 2-tuple (matrix norm), only 'euclidean', 'fro', `1`, 

654 `2`, `np.inf` are supported. 

655 See the description of `axis` on how to compute norms for a batch of 

656 vectors or matrices stored in a tensor. 

657 axis: If `axis` is `None` (the default), the input is considered a vector 

658 and a single vector norm is computed over the entire set of values in the 

659 tensor, i.e. `norm(tensor, ord=ord)` is equivalent to 

660 `norm(reshape(tensor, [-1]), ord=ord)`. 

661 If `axis` is a Python integer, the input is considered a batch of vectors, 

662 and `axis` determines the axis in `tensor` over which to compute vector 

663 norms. 

664 If `axis` is a 2-tuple of Python integers it is considered a batch of 

665 matrices and `axis` determines the axes in `tensor` over which to compute 

666 a matrix norm. 

667 Negative indices are supported. Example: If you are passing a tensor that 

668 can be either a matrix or a batch of matrices at runtime, pass 

669 `axis=[-2,-1]` instead of `axis=None` to make sure that matrix norms are 

670 computed. 

671 keepdims: If True, the axis indicated in `axis` are kept with size 1. 

672 Otherwise, the dimensions in `axis` are removed from the output shape. 

673 name: The name of the op. 

674 keep_dims: Deprecated alias for `keepdims`. 

675 

676 Returns: 

677 output: A `Tensor` of the same type as tensor, containing the vector or 

678 matrix norms. If `keepdims` is True then the rank of output is equal to 

679 the rank of `tensor`. Otherwise, if `axis` is none the output is a scalar, 

680 if `axis` is an integer, the rank of `output` is one less than the rank 

681 of `tensor`, if `axis` is a 2-tuple the rank of `output` is two less 

682 than the rank of `tensor`. 

683 

684 Raises: 

685 ValueError: If `ord` or `axis` is invalid. 

686 

687 @compatibility(numpy) 

688 Mostly equivalent to numpy.linalg.norm. 

689 Not supported: ord <= 0, 2-norm for matrices, nuclear norm. 

690 Other differences: 

691 a) If axis is `None`, treats the flattened `tensor` as a vector 

692 regardless of rank. 

693 b) Explicitly supports 'euclidean' norm as the default, including for 

694 higher order tensors. 

695 @end_compatibility 

696 """ 

697 keepdims = deprecation.deprecated_argument_lookup('keepdims', keepdims, 

698 'keep_dims', keep_dims) 

699 if keepdims is None: 

700 keepdims = False 

701 

702 is_matrix_norm = ((isinstance(axis, tuple) or isinstance(axis, list)) and 

703 len(axis) == 2) 

704 if is_matrix_norm: 

705 axis = tuple(axis) 

706 if (not isinstance(axis[0], int) or not isinstance(axis[1], int) or 

707 axis[0] == axis[1]): 

708 raise ValueError( 

709 "'axis' must be None, an integer, or a tuple of 2 " 

710 f"unique integers, got {axis}") 

711 supported_matrix_norms = ['euclidean', 'fro', 1, 2, np.inf] 

712 if ord not in supported_matrix_norms: 

713 raise ValueError(f"'ord' must be a supported matrix norm in " 

714 f"{supported_matrix_norms}, got {ord}") 

715 else: 

716 if not (isinstance(axis, int) or axis is None): 

717 raise ValueError( 

718 "'axis' must be None, an integer, or a " 

719 f"tuple of 2 unique integers, got {axis}") 

720 

721 supported_vector_norms = ['euclidean', 1, 2, np.inf] 

722 if (not np.isreal(ord) or ord <= 0) and ord not in supported_vector_norms: 

723 raise ValueError(f"'ord' must be a supported vector norm, got {ord}") 

724 if axis is not None: 

725 axis = (axis,) 

726 

727 with ops.name_scope(name, 'norm', [tensor]): 

728 tensor = ops.convert_to_tensor(tensor) 

729 

730 if ord in ['fro', 'euclidean', 2, 2.0]: 

731 if is_matrix_norm and ord in [2, 2.0]: 

732 rank = array_ops.rank(tensor) 

733 positive_axis = map_fn.map_fn( 

734 lambda i: cond.cond( 

735 i >= 0, 

736 lambda: i, 

737 lambda: i + rank), 

738 ops.convert_to_tensor(axis)) 

739 axes = math_ops.range(rank) 

740 perm_before = array_ops.concat([ 

741 gen_array_ops.list_diff(axes, positive_axis, dtypes.int32)[0], 

742 positive_axis 

743 ], 

744 axis=0) 

745 perm_after = map_fn.map_fn( 

746 lambda i: math_ops.cast( 

747 array_ops.squeeze( 

748 array_ops.where_v2(math_ops.equal(perm_before, i))), 

749 dtype=dtypes.int32), axes) 

750 permed = array_ops.transpose(tensor, perm=perm_before) 

751 matrix_2_norm = array_ops.expand_dims( 

752 math_ops.reduce_max( 

753 math_ops.abs(gen_linalg_ops.svd(permed, compute_uv=False)[0]), 

754 axis=-1, 

755 keepdims=True), 

756 axis=-1) 

757 result = array_ops.transpose(matrix_2_norm, perm=perm_after) 

758 else: 

759 # NOTE: we unfortunately cannot use tf.math.reduce_euclidean_norm, since 

760 # this introduces a new op that is not supported in XLA, and breaks 

761 # many existing TPU workloads (e.g. ResNet). 

762 result = math_ops.sqrt( 

763 math_ops.reduce_sum( 

764 tensor * math_ops.conj(tensor), axis, keepdims=True)) 

765 else: 

766 result = math_ops.abs(tensor) 

767 if ord == 1: 

768 sum_axis = None if axis is None else axis[0] 

769 result = math_ops.reduce_sum(result, sum_axis, keepdims=True) 

770 if is_matrix_norm: 

771 result = math_ops.reduce_max(result, axis[-1], keepdims=True) 

772 elif ord == np.inf: 

773 if is_matrix_norm: 

774 result = math_ops.reduce_sum(result, axis[1], keepdims=True) 

775 max_axis = None if axis is None else axis[0] 

776 result = math_ops.reduce_max(result, max_axis, keepdims=True) 

777 else: 

778 # General p-norms (positive p only) 

779 result = math_ops.pow( 

780 math_ops.reduce_sum(math_ops.pow(result, ord), axis, keepdims=True), 

781 1.0 / ord) 

782 if not keepdims: 

783 result = array_ops.squeeze(result, axis) 

784 return result 

785 

786 

787# pylint: enable=invalid-name,redefined-builtin