diff --git a/tensorflow/g3doc/api_docs/python/array_ops.md b/tensorflow/g3doc/api_docs/python/array_ops.md
index 33c543dd621..27a4f935d0d 100644
--- a/tensorflow/g3doc/api_docs/python/array_ops.md
+++ b/tensorflow/g3doc/api_docs/python/array_ops.md
@@ -728,8 +728,6 @@ tf.strided_slice(input, [1, 1, 0], [2, -1, 3], [1, -1, 1]) ==>[[[4, 4, 4],
DEPRECATED: use split_v; split_v rename to split happening soon.
-Splits a tensor into `num_split` tensors along one dimension.
-
Splits `value` along dimension `axis` into `num_or_size_splits` smaller
tensors. Requires that `num_or_size_splits` evenly divide `value.shape[axis]`.
@@ -769,7 +767,7 @@ tf.unpack(t, axis=axis)
##### Returns:
- `num_split` `Tensor` objects resulting from splitting `value`.
+ `num_or_size_splits` `Tensor` objects resulting from splitting `value`.
- - -
@@ -778,13 +776,13 @@ tf.unpack(t, axis=axis)
Splits a tensor into sub tensors.
-If num_or_size_splits is a scalar, `num_split`, then
-splits `value` along dimension `axis` into `num_split` smaller tensors.
-Requires that `num_split` evenly divide `value.shape[split_dim]`.
+If `num_or_size_splits` is a scalar, `num_split`, then splits `value` along
+dimension `axis` into `num_split` smaller tensors.
+Requires that `num_split` evenly divides `value.shape[axis]`.
-If num_or_size_splits is a tensor, then
-splits `value` into len(size_splits) pieces each the same size as the input
-except along dimension split_dim where the size is size_splits[i].
+If `num_or_size_splits` is a tensor, `size_splits`, then splits `value` into
+`len(size_splits)` pieces. The shape of the `i`-th piece has the same size as
+the `value` except along dimension `axis` where the size is `size_splits[i]`.
For example:
@@ -807,12 +805,12 @@ tf.shape(split0) ==> [5, 10]
* `num_or_size_splits`: Either an integer indicating the number of splits along
split_dim or a 1-D Tensor containing the sizes of each output tensor
along split_dim. If an integer then it must evenly divide
- value.shape[split_dim]; otherwise the sum of sizes along the split
- dimension must match that of the input.
+ `value.shape[axis]`; otherwise the sum of sizes along the split
+ dimension must match that of the `value`.
* `axis`: A 0-D `int32` `Tensor`. The dimension along which to split.
Must be in the range `[0, rank(value))`. Defaults to 0.
* `num`: Optional, used to specify the number of outputs when it cannot be
- inferred from the shape of size_splits.
+ inferred from the shape of `size_splits`.
* `name`: A name for the operation (optional).
##### Returns:
diff --git a/tensorflow/g3doc/api_docs/python/contrib.linalg.md b/tensorflow/g3doc/api_docs/python/contrib.linalg.md
index 146aaf515f4..33f0087dd98 100644
--- a/tensorflow/g3doc/api_docs/python/contrib.linalg.md
+++ b/tensorflow/g3doc/api_docs/python/contrib.linalg.md
@@ -29,7 +29,7 @@ Subclasses of `LinearOperator` provide a access to common methods on a
* Operators that take advantage of special structure, while providing a
consistent API to users.
-### Subclassing
+#### Subclassing
To enable a public method, subclasses should implement the leading-underscore
version of the method. The argument signature should be identical except for
@@ -37,7 +37,7 @@ the omission of `name="..."`. For example, to enable
`apply(x, adjoint=False, name="apply")` a subclass should implement
`_apply(x, adjoint=False)`.
-### Performance contract
+#### Performance contract
Subclasses should implement a method only if it can be done with a reasonable
performance increase over generic dense operations, either in time, parallel
@@ -49,7 +49,7 @@ Class docstrings should contain an explanation of computational complexity.
Since this is a high-performance library, attention should be paid to detail,
and explanations can include constants as well as Big-O notation.
-### Shape compatibility
+#### Shape compatibility
`LinearOperator` sub classes should operate on a [batch] matrix with
compatible shape. Class docstrings should define what is meant by compatible
@@ -71,7 +71,7 @@ operator.shape = [B1,...,Bb] + [M, N], b >= 0,
rhs.shape = [B1,...,Bb] + [M, R]
```
-### Example docstring for subclasses.
+#### Example docstring for subclasses.
This operator acts like a (batch) matrix `A` with shape
`[B1,...,Bb, M, N]` for some `b >= 0`. The first `b` indices index a
@@ -98,19 +98,19 @@ operator.apply(x)
==> Shape [2, 4, 5] Tensor
```
-### Shape compatibility
+#### Shape compatibility
This operator acts on batch matrices with compatible shape.
FILL IN WHAT IS MEANT BY COMPATIBLE SHAPE
-### Performance
+#### Performance
FILL THIS IN
-### Matrix property hints
+#### Matrix property hints
This `LinearOperator` is initialized with boolean flags of the form `is_X`,
-for `X = non_singular, self_adjoint` etc...
+for `X = non_singular, self_adjoint, positive_definite`.
These have the following meaning
* If `is_X == True`, callers should expect the operator to have the
property `X`. This is a promise that should be fulfilled, but is *not* a
@@ -282,8 +282,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -376,8 +375,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -533,7 +531,7 @@ Return a dense (batch) matrix representing this operator.
`LinearOperator` acting like a [batch] square diagonal matrix.
-This operator acts like a [batch] matrix `A` with shape
+This operator acts like a [batch] diagonal matrix `A` with shape
`[B1,...,Bb, N, N]` for some `b >= 0`. The first `b` indices index a
batch member. For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
an `N x N` matrix. This matrix `A` is not materialized, but for
@@ -572,7 +570,7 @@ x = operator.solve(y)
==> operator.apply(x) = y
```
-### Shape compatibility
+#### Shape compatibility
This operator acts on [batch] matrix with compatible shape.
`x` is a batch matrix with compatible shape for `apply` and `solve` if
@@ -583,22 +581,22 @@ x.shape = [C1,...,Cc] + [N, R],
and [C1,...,Cc] broadcasts with [B1,...,Bb] to [D1,...,Dd]
```
-### Performance
+#### Performance
Suppose `operator` is a `LinearOperatorDiag` of shape `[N, N]`,
and `x.shape = [N, R]`. Then
-* `operator.apply(x)` involves `N*R` multiplications.
-* `operator.solve(x)` involves `N` divisions and `N*R` multiplications.
+* `operator.apply(x)` involves `N * R` multiplications.
+* `operator.solve(x)` involves `N` divisions and `N * R` multiplications.
* `operator.determinant()` involves a size `N` `reduce_prod`.
If instead `operator` and `x` have shape `[B1,...,Bb, N, N]` and
`[B1,...,Bb, N, R]`, every operation increases in complexity by `B1*...*Bb`.
-### Matrix property hints
+#### Matrix property hints
This `LinearOperator` is initialized with boolean flags of the form `is_X`,
-for `X = non_singular, self_adjoint` etc...
+for `X = non_singular, self_adjoint, positive_definite`.
These have the following meaning
* If `is_X == True`, callers should expect the operator to have the
property `X`. This is a promise that should be fulfilled, but is *not* a
@@ -767,8 +765,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -861,8 +858,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -1009,13 +1005,487 @@ Return a dense (batch) matrix representing this operator.
+- - -
+
+### `class tf.contrib.linalg.LinearOperatorMatrix` {#LinearOperatorMatrix}
+
+`LinearOperator` that wraps a [batch] matrix.
+
+This operator wraps a [batch] matrix `A` (which is a `Tensor`) with shape
+`[B1,...,Bb, M, N]` for some `b >= 0`. The first `b` indices index a
+batch member. For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
+an `M x N` matrix.
+
+```python
+# Create a 2 x 2 linear operator.
+matrix = [[1., 2.], [3., 4.]]
+operator = LinearOperatorMatrix(matrix)
+
+operator.to_dense()
+==> [[1., 2.]
+ [3., 4.]]
+
+operator.shape
+==> [2, 2]
+
+operator.log_determinant()
+==> scalar Tensor
+
+x = ... Shape [2, 4] Tensor
+operator.apply(x)
+==> Shape [2, 4] Tensor
+
+# Create a [2, 3] batch of 4 x 4 linear operators.
+matrix = tf.random_normal(shape=[2, 3, 4, 4])
+operator = LinearOperatorMatrix(matrix)
+```
+
+#### Shape compatibility
+
+This operator acts on [batch] matrix with compatible shape.
+`x` is a batch matrix with compatible shape for `apply` and `solve` if
+
+```
+operator.shape = [B1,...,Bb] + [M, N], with b >= 0
+x.shape = [B1,...,Bb] + [N, R], with R >= 0.
+```
+
+#### Performance
+
+`LinearOperatorMatrix` has exactly the same performance as would be achieved
+by using standard `TensorFlow` matrix ops. Intelligent choices are made
+based on the following initialization hints.
+
+* If `dtype` is real, and `is_self_adjoint` and `is_positive_definite`, a
+ Cholesky factorization is used for the determinant and solve.
+
+In all cases, suppose `operator` is a `LinearOperatorMatrix` of shape
+`[M, N]`, and `x.shape = [N, R]`. Then
+
+* `operator.apply(x)` is `O(M * N * R)`.
+* If `M=N`, `operator.solve(x)` is `O(N^3 * R)`.
+* If `M=N`, `operator.determinant()` is `O(N^3)`.
+
+If instead `operator` and `x` have shape `[B1,...,Bb, M, N]` and
+`[B1,...,Bb, N, R]`, every operation increases in complexity by `B1*...*Bb`.
+
+#### Matrix property hints
+
+This `LinearOperator` is initialized with boolean flags of the form `is_X`,
+for `X = non_singular, self_adjoint, positive_definite`.
+These have the following meaning
+* If `is_X == True`, callers should expect the operator to have the
+ property `X`. This is a promise that should be fulfilled, but is *not* a
+ runtime assert. For example, finite floating point precision may result
+ in these promises being violated.
+* If `is_X == False`, callers should expect the operator to not have `X`.
+* If `is_X == None` (the default), callers should have no expectation either
+ way.
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.__init__(matrix, is_non_singular=None, is_self_adjoint=None, is_positive_definite=None, name='LinearOperatorMatrix')` {#LinearOperatorMatrix.__init__}
+
+Initialize a `LinearOperatorMatrix`.
+
+##### Args:
+
+
+* `matrix`: Shape `[B1,...,Bb, M, N]` with `b >= 0`, `M, N >= 0`.
+ Allowed dtypes: `float32`, `float64`, `complex64`, `complex128`.
+* `is_non_singular`: Expect that this operator is non-singular.
+* `is_self_adjoint`: Expect that this operator is equal to its hermitian
+ transpose.
+* `is_positive_definite`: Expect that this operator is positive definite,
+ meaning the real part of all eigenvalues is positive. We do not require
+ the operator to be self-adjoint to be positive-definite. See:
+* `https`: //en.wikipedia.org/wiki/Positive-definite_matrix
+ #Extension_for_non_symmetric_matrices
+* `name`: A name for this `LinearOperator`.
+
+##### Raises:
+
+
+* `TypeError`: If `diag.dtype` is not an allowed type.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.add_to_tensor(x, name='add_to_tensor')` {#LinearOperatorMatrix.add_to_tensor}
+
+Add matrix represented by this operator to `x`. Equivalent to `A + x`.
+
+##### Args:
+
+
+* `x`: `Tensor` with same `dtype` and shape broadcastable to `self.shape`.
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ A `Tensor` with broadcast shape and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.apply(x, adjoint=False, name='apply')` {#LinearOperatorMatrix.apply}
+
+Transform `x` with left multiplication: `x --> Ax`.
+
+##### Args:
+
+
+* `x`: `Tensor` with compatible shape and same `dtype` as `self`.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, left multiply by the adjoint.
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ A `Tensor` with shape `[..., M, R]` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.assert_non_singular(name='assert_non_singular')` {#LinearOperatorMatrix.assert_non_singular}
+
+Returns an `Op` that asserts this operator is non singular.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.assert_positive_definite(name='assert_positive_definite')` {#LinearOperatorMatrix.assert_positive_definite}
+
+Returns an `Op` that asserts this operator is positive definite.
+
+Here, positive definite means the real part of all eigenvalues is positive.
+We do not require the operator to be self-adjoint.
+
+##### Args:
+
+
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ An `Op` that asserts this operator is positive definite.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.assert_self_adjoint(name='assert_self_adjoint')` {#LinearOperatorMatrix.assert_self_adjoint}
+
+Returns an `Op` that asserts this operator is self-adjoint.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.batch_shape` {#LinearOperatorMatrix.batch_shape}
+
+`TensorShape` of batch dimensions of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb])`, equivalent to `A.get_shape()[:-2]`
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.batch_shape_dynamic(name='batch_shape_dynamic')` {#LinearOperatorMatrix.batch_shape_dynamic}
+
+Shape of batch dimensions of this operator, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb]`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.determinant(name='det')` {#LinearOperatorMatrix.determinant}
+
+Determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.domain_dimension` {#LinearOperatorMatrix.domain_dimension}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.domain_dimension_dynamic(name='domain_dimension_dynamic')` {#LinearOperatorMatrix.domain_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.dtype` {#LinearOperatorMatrix.dtype}
+
+The `DType` of `Tensor`s handled by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.graph_parents` {#LinearOperatorMatrix.graph_parents}
+
+List of graph dependencies of this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.is_non_singular` {#LinearOperatorMatrix.is_non_singular}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.is_positive_definite` {#LinearOperatorMatrix.is_positive_definite}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.is_self_adjoint` {#LinearOperatorMatrix.is_self_adjoint}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.log_abs_determinant(name='log_abs_det')` {#LinearOperatorMatrix.log_abs_determinant}
+
+Log absolute value of determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.name` {#LinearOperatorMatrix.name}
+
+Name prepended to all ops created by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.range_dimension` {#LinearOperatorMatrix.range_dimension}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.range_dimension_dynamic(name='range_dimension_dynamic')` {#LinearOperatorMatrix.range_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.shape` {#LinearOperatorMatrix.shape}
+
+`TensorShape` of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb, M, N])`, equivalent to `A.get_shape()`.
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.shape_dynamic(name='shape_dynamic')` {#LinearOperatorMatrix.shape_dynamic}
+
+Shape of this `LinearOperator`, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb, M, N]`, equivalent to `tf.shape(A)`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.solve(rhs, adjoint=False, name='solve')` {#LinearOperatorMatrix.solve}
+
+Solve `R` (batch) systems of equations exactly: `A X = rhs`.
+
+Examples:
+
+```python
+# Create an operator acting like a 10 x 2 x 2 matrix.
+operator = LinearOperator(...)
+operator.shape # = 10 x 2 x 2
+
+# Solve one linear system (R = 1) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 1
+X = operator.solve(RHS) # shape 10 x 2 x 1
+
+# Solve five linear systems (R = 5) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 5
+X = operator.solve(RHS)
+X[3, :, 2] # Solution to the linear system A[3, :, :] X = RHS[3, :, 2]
+```
+
+##### Args:
+
+
+* `rhs`: `Tensor` with same `dtype` as this operator and compatible shape.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, solve the system involving the adjoint
+ of this `LinearOperator`.
+* `name`: A name scope to use for ops added by this method.
+
+##### Returns:
+
+ `Tensor` with shape `[...,N, R]` and same `dtype` as `rhs`.
+
+##### Raises:
+
+
+* `ValueError`: If self.is_non_singular is False.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.tensor_rank` {#LinearOperatorMatrix.tensor_rank}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ Python integer, or None if the tensor rank is undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.tensor_rank_dynamic(name='tensor_rank_dynamic')` {#LinearOperatorMatrix.tensor_rank_dynamic}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`, determined at runtime.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.to_dense(name='to_dense')` {#LinearOperatorMatrix.to_dense}
+
+Return a dense (batch) matrix representing this operator.
+
+
+
- - -
### `class tf.contrib.linalg.LinearOperatorTriL` {#LinearOperatorTriL}
`LinearOperator` acting like a [batch] square lower triangular matrix.
-This operator acts like a [batch] matrix `A` with shape
+This operator acts like a [batch] lower triangular matrix `A` with shape
`[B1,...,Bb, N, N]` for some `b >= 0`. The first `b` indices index a
batch member. For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
an `N x N` matrix.
@@ -1046,16 +1516,9 @@ operator.apply(x)
# Create a [2, 3] batch of 4 x 4 linear operators.
tril = tf.random_normal(shape=[2, 3, 4, 4])
operator = LinearOperatorTriL(tril)
-
-# Create a shape [2, 1, 4, 2] vector. Note that this shape is compatible
-# since the batch dimensions, [2, 1], are brodcast to
-# operator.batch_shape = [2, 3].
-y = tf.random_normal(shape=[2, 1, 4, 2])
-x = operator.solve(y)
-==> operator.apply(x) = y
```
-### Shape compatibility
+#### Shape compatibility
This operator acts on [batch] matrix with compatible shape.
`x` is a batch matrix with compatible shape for `apply` and `solve` if
@@ -1065,7 +1528,7 @@ operator.shape = [B1,...,Bb] + [N, N], with b >= 0
x.shape = [B1,...,Bb] + [N, R], with R >= 0.
```
-### Performance
+#### Performance
Suppose `operator` is a `LinearOperatorTriL` of shape `[N, N]`,
and `x.shape = [N, R]`. Then
@@ -1077,10 +1540,10 @@ and `x.shape = [N, R]`. Then
If instead `operator` and `x` have shape `[B1,...,Bb, N, N]` and
`[B1,...,Bb, N, R]`, every operation increases in complexity by `B1*...*Bb`.
-### Matrix property hints
+#### Matrix property hints
This `LinearOperator` is initialized with boolean flags of the form `is_X`,
-for `X = non_singular, self_adjoint` etc...
+for `X = non_singular, self_adjoint, positive_definite`.
These have the following meaning
* If `is_X == True`, callers should expect the operator to have the
property `X`. This is a promise that should be fulfilled, but is *not* a
@@ -1252,8 +1715,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -1346,8 +1808,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -1494,3 +1955,497 @@ Return a dense (batch) matrix representing this operator.
+
+### Transformations and Combinations of operators
+
+- - -
+
+### `class tf.contrib.linalg.LinearOperatorComposition` {#LinearOperatorComposition}
+
+Composes one or more `LinearOperators`.
+
+This operator composes one or more linear operators `[op1,...,opJ]`,
+building a new `LinearOperator` with action defined by:
+
+```
+op_composed(x) := op1(op2(...(opJ(x)...))
+```
+
+If `opj` acts like [batch] matrix `Aj`, then `op_composed` acts like the
+[batch] matrix formed with the multiplication `A1 A2...AJ`.
+
+If `opj` has shape `batch_shape_j + [M_j, N_j]`, then we must have
+`N_j = M_{j+1}`, in which case the composed operator has shape equal to
+`broadcast_batch_shape + [M_1, N_J]`, where `broadcast_batch_shape` is the
+mutual broadcast of `batch_shape_j`, `j = 1,...,J`, assuming the intermediate
+batch shapes broadcast. Even if the composed shape is well defined, the
+composed operator's methods may fail due to lack of broadcasting ability in
+the defining operators' methods.
+
+```python
+# Create a 2 x 2 linear operator composed of two 2 x 2 operators.
+operator_1 = LinearOperatorMatrix([[1., 2.], [3., 4.]])
+operator_2 = LinearOperatorMatrix([[1., 0.], [0., 1.]])
+operator = LinearOperatorComposition([operator_1, operator_2])
+
+operator.to_dense()
+==> [[1., 2.]
+ [3., 4.]]
+
+operator.shape
+==> [2, 2]
+
+operator.log_determinant()
+==> scalar Tensor
+
+x = ... Shape [2, 4] Tensor
+operator.apply(x)
+==> Shape [2, 4] Tensor
+
+# Create a [2, 3] batch of 4 x 5 linear operators.
+matrix_45 = tf.random_normal(shape=[2, 3, 4, 5])
+operator_45 = LinearOperatorMatrix(matrix)
+
+# Create a [2, 3] batch of 5 x 6 linear operators.
+matrix_56 = tf.random_normal(shape=[2, 3, 5, 6])
+operator_56 = LinearOperatorMatrix(matrix_56)
+
+# Compose to create a [2, 3] batch of 4 x 6 operators.
+opeartor_46 = LinearOperatorComposition([operator_45, operator_56])
+
+# Create a shape [2, 3, 6, 2] vector.
+x = tf.random_normal(shape=[2, 3, 6, 2])
+operator.apply(x)
+==> Shape [2, 3, 4, 2] Tensor
+```
+
+#### Performance
+
+The performance of `LinearOperatorComposition` on any operation is equal to
+the sum of the individual operators' operations.
+
+
+#### Matrix property hints
+
+This `LinearOperator` is initialized with boolean flags of the form `is_X`,
+for `X = non_singular, self_adjoint, positive_definite`.
+These have the following meaning
+* If `is_X == True`, callers should expect the operator to have the
+ property `X`. This is a promise that should be fulfilled, but is *not* a
+ runtime assert. For example, finite floating point precision may result
+ in these promises being violated.
+* If `is_X == False`, callers should expect the operator to not have `X`.
+* If `is_X == None` (the default), callers should have no expectation either
+ way.
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.__init__(operators, is_non_singular=None, is_self_adjoint=None, is_positive_definite=None, name=None)` {#LinearOperatorComposition.__init__}
+
+Initialize a `LinearOperatorComposition`.
+
+`LinearOperatorComposition` is initialized with a list of operators
+`[op_1,...,op_J]`. For the `apply` method to be well defined, the
+composition `op_i.apply(op_{i+1}(x))` must be defined. Other methods have
+similar constraints.
+
+##### Args:
+
+
+* `operators`: Iterable of `LinearOperator` objects, each with
+ the same `dtype` and composible shape.
+* `is_non_singular`: Expect that this operator is non-singular.
+* `is_self_adjoint`: Expect that this operator is equal to its hermitian
+ transpose.
+* `is_positive_definite`: Expect that this operator is positive definite,
+ meaning the real part of all eigenvalues is positive. We do not require
+ the operator to be self-adjoint to be positive-definite. See:
+* `https`: //en.wikipedia.org/wiki/Positive-definite_matrix
+ #Extension_for_non_symmetric_matrices
+* `name`: A name for this `LinearOperator`. Default is the individual
+ operators names joined with `_o_`.
+
+##### Raises:
+
+
+* `TypeError`: If all operators do not have the same `dtype`.
+* `ValueError`: If `operators` is empty.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.add_to_tensor(x, name='add_to_tensor')` {#LinearOperatorComposition.add_to_tensor}
+
+Add matrix represented by this operator to `x`. Equivalent to `A + x`.
+
+##### Args:
+
+
+* `x`: `Tensor` with same `dtype` and shape broadcastable to `self.shape`.
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ A `Tensor` with broadcast shape and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.apply(x, adjoint=False, name='apply')` {#LinearOperatorComposition.apply}
+
+Transform `x` with left multiplication: `x --> Ax`.
+
+##### Args:
+
+
+* `x`: `Tensor` with compatible shape and same `dtype` as `self`.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, left multiply by the adjoint.
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ A `Tensor` with shape `[..., M, R]` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.assert_non_singular(name='assert_non_singular')` {#LinearOperatorComposition.assert_non_singular}
+
+Returns an `Op` that asserts this operator is non singular.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.assert_positive_definite(name='assert_positive_definite')` {#LinearOperatorComposition.assert_positive_definite}
+
+Returns an `Op` that asserts this operator is positive definite.
+
+Here, positive definite means the real part of all eigenvalues is positive.
+We do not require the operator to be self-adjoint.
+
+##### Args:
+
+
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ An `Op` that asserts this operator is positive definite.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.assert_self_adjoint(name='assert_self_adjoint')` {#LinearOperatorComposition.assert_self_adjoint}
+
+Returns an `Op` that asserts this operator is self-adjoint.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.batch_shape` {#LinearOperatorComposition.batch_shape}
+
+`TensorShape` of batch dimensions of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb])`, equivalent to `A.get_shape()[:-2]`
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.batch_shape_dynamic(name='batch_shape_dynamic')` {#LinearOperatorComposition.batch_shape_dynamic}
+
+Shape of batch dimensions of this operator, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb]`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.determinant(name='det')` {#LinearOperatorComposition.determinant}
+
+Determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.domain_dimension` {#LinearOperatorComposition.domain_dimension}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.domain_dimension_dynamic(name='domain_dimension_dynamic')` {#LinearOperatorComposition.domain_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.dtype` {#LinearOperatorComposition.dtype}
+
+The `DType` of `Tensor`s handled by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.graph_parents` {#LinearOperatorComposition.graph_parents}
+
+List of graph dependencies of this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.is_non_singular` {#LinearOperatorComposition.is_non_singular}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.is_positive_definite` {#LinearOperatorComposition.is_positive_definite}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.is_self_adjoint` {#LinearOperatorComposition.is_self_adjoint}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.log_abs_determinant(name='log_abs_det')` {#LinearOperatorComposition.log_abs_determinant}
+
+Log absolute value of determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.name` {#LinearOperatorComposition.name}
+
+Name prepended to all ops created by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.operators` {#LinearOperatorComposition.operators}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.range_dimension` {#LinearOperatorComposition.range_dimension}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.range_dimension_dynamic(name='range_dimension_dynamic')` {#LinearOperatorComposition.range_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.shape` {#LinearOperatorComposition.shape}
+
+`TensorShape` of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb, M, N])`, equivalent to `A.get_shape()`.
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.shape_dynamic(name='shape_dynamic')` {#LinearOperatorComposition.shape_dynamic}
+
+Shape of this `LinearOperator`, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb, M, N]`, equivalent to `tf.shape(A)`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.solve(rhs, adjoint=False, name='solve')` {#LinearOperatorComposition.solve}
+
+Solve `R` (batch) systems of equations exactly: `A X = rhs`.
+
+Examples:
+
+```python
+# Create an operator acting like a 10 x 2 x 2 matrix.
+operator = LinearOperator(...)
+operator.shape # = 10 x 2 x 2
+
+# Solve one linear system (R = 1) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 1
+X = operator.solve(RHS) # shape 10 x 2 x 1
+
+# Solve five linear systems (R = 5) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 5
+X = operator.solve(RHS)
+X[3, :, 2] # Solution to the linear system A[3, :, :] X = RHS[3, :, 2]
+```
+
+##### Args:
+
+
+* `rhs`: `Tensor` with same `dtype` as this operator and compatible shape.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, solve the system involving the adjoint
+ of this `LinearOperator`.
+* `name`: A name scope to use for ops added by this method.
+
+##### Returns:
+
+ `Tensor` with shape `[...,N, R]` and same `dtype` as `rhs`.
+
+##### Raises:
+
+
+* `ValueError`: If self.is_non_singular is False.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.tensor_rank` {#LinearOperatorComposition.tensor_rank}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ Python integer, or None if the tensor rank is undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.tensor_rank_dynamic(name='tensor_rank_dynamic')` {#LinearOperatorComposition.tensor_rank_dynamic}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`, determined at runtime.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.to_dense(name='to_dense')` {#LinearOperatorComposition.to_dense}
+
+Return a dense (batch) matrix representing this operator.
+
+
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.linalg.LinearOperatorDiag.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.linalg.LinearOperatorDiag.md
index f2c6c8cf6ca..a449b2f097f 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.linalg.LinearOperatorDiag.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.contrib.linalg.LinearOperatorDiag.md
@@ -1,6 +1,6 @@
`LinearOperator` acting like a [batch] square diagonal matrix.
-This operator acts like a [batch] matrix `A` with shape
+This operator acts like a [batch] diagonal matrix `A` with shape
`[B1,...,Bb, N, N]` for some `b >= 0`. The first `b` indices index a
batch member. For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
an `N x N` matrix. This matrix `A` is not materialized, but for
@@ -39,7 +39,7 @@ x = operator.solve(y)
==> operator.apply(x) = y
```
-### Shape compatibility
+#### Shape compatibility
This operator acts on [batch] matrix with compatible shape.
`x` is a batch matrix with compatible shape for `apply` and `solve` if
@@ -50,22 +50,22 @@ x.shape = [C1,...,Cc] + [N, R],
and [C1,...,Cc] broadcasts with [B1,...,Bb] to [D1,...,Dd]
```
-### Performance
+#### Performance
Suppose `operator` is a `LinearOperatorDiag` of shape `[N, N]`,
and `x.shape = [N, R]`. Then
-* `operator.apply(x)` involves `N*R` multiplications.
-* `operator.solve(x)` involves `N` divisions and `N*R` multiplications.
+* `operator.apply(x)` involves `N * R` multiplications.
+* `operator.solve(x)` involves `N` divisions and `N * R` multiplications.
* `operator.determinant()` involves a size `N` `reduce_prod`.
If instead `operator` and `x` have shape `[B1,...,Bb, N, N]` and
`[B1,...,Bb, N, R]`, every operation increases in complexity by `B1*...*Bb`.
-### Matrix property hints
+#### Matrix property hints
This `LinearOperator` is initialized with boolean flags of the form `is_X`,
-for `X = non_singular, self_adjoint` etc...
+for `X = non_singular, self_adjoint, positive_definite`.
These have the following meaning
* If `is_X == True`, callers should expect the operator to have the
property `X`. This is a promise that should be fulfilled, but is *not* a
@@ -234,8 +234,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -328,8 +327,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.contrib.linalg.LinearOperatorComposition.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.contrib.linalg.LinearOperatorComposition.md
new file mode 100644
index 00000000000..5e051e5ba8d
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.contrib.linalg.LinearOperatorComposition.md
@@ -0,0 +1,486 @@
+Composes one or more `LinearOperators`.
+
+This operator composes one or more linear operators `[op1,...,opJ]`,
+building a new `LinearOperator` with action defined by:
+
+```
+op_composed(x) := op1(op2(...(opJ(x)...))
+```
+
+If `opj` acts like [batch] matrix `Aj`, then `op_composed` acts like the
+[batch] matrix formed with the multiplication `A1 A2...AJ`.
+
+If `opj` has shape `batch_shape_j + [M_j, N_j]`, then we must have
+`N_j = M_{j+1}`, in which case the composed operator has shape equal to
+`broadcast_batch_shape + [M_1, N_J]`, where `broadcast_batch_shape` is the
+mutual broadcast of `batch_shape_j`, `j = 1,...,J`, assuming the intermediate
+batch shapes broadcast. Even if the composed shape is well defined, the
+composed operator's methods may fail due to lack of broadcasting ability in
+the defining operators' methods.
+
+```python
+# Create a 2 x 2 linear operator composed of two 2 x 2 operators.
+operator_1 = LinearOperatorMatrix([[1., 2.], [3., 4.]])
+operator_2 = LinearOperatorMatrix([[1., 0.], [0., 1.]])
+operator = LinearOperatorComposition([operator_1, operator_2])
+
+operator.to_dense()
+==> [[1., 2.]
+ [3., 4.]]
+
+operator.shape
+==> [2, 2]
+
+operator.log_determinant()
+==> scalar Tensor
+
+x = ... Shape [2, 4] Tensor
+operator.apply(x)
+==> Shape [2, 4] Tensor
+
+# Create a [2, 3] batch of 4 x 5 linear operators.
+matrix_45 = tf.random_normal(shape=[2, 3, 4, 5])
+operator_45 = LinearOperatorMatrix(matrix)
+
+# Create a [2, 3] batch of 5 x 6 linear operators.
+matrix_56 = tf.random_normal(shape=[2, 3, 5, 6])
+operator_56 = LinearOperatorMatrix(matrix_56)
+
+# Compose to create a [2, 3] batch of 4 x 6 operators.
+opeartor_46 = LinearOperatorComposition([operator_45, operator_56])
+
+# Create a shape [2, 3, 6, 2] vector.
+x = tf.random_normal(shape=[2, 3, 6, 2])
+operator.apply(x)
+==> Shape [2, 3, 4, 2] Tensor
+```
+
+#### Performance
+
+The performance of `LinearOperatorComposition` on any operation is equal to
+the sum of the individual operators' operations.
+
+
+#### Matrix property hints
+
+This `LinearOperator` is initialized with boolean flags of the form `is_X`,
+for `X = non_singular, self_adjoint, positive_definite`.
+These have the following meaning
+* If `is_X == True`, callers should expect the operator to have the
+ property `X`. This is a promise that should be fulfilled, but is *not* a
+ runtime assert. For example, finite floating point precision may result
+ in these promises being violated.
+* If `is_X == False`, callers should expect the operator to not have `X`.
+* If `is_X == None` (the default), callers should have no expectation either
+ way.
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.__init__(operators, is_non_singular=None, is_self_adjoint=None, is_positive_definite=None, name=None)` {#LinearOperatorComposition.__init__}
+
+Initialize a `LinearOperatorComposition`.
+
+`LinearOperatorComposition` is initialized with a list of operators
+`[op_1,...,op_J]`. For the `apply` method to be well defined, the
+composition `op_i.apply(op_{i+1}(x))` must be defined. Other methods have
+similar constraints.
+
+##### Args:
+
+
+* `operators`: Iterable of `LinearOperator` objects, each with
+ the same `dtype` and composible shape.
+* `is_non_singular`: Expect that this operator is non-singular.
+* `is_self_adjoint`: Expect that this operator is equal to its hermitian
+ transpose.
+* `is_positive_definite`: Expect that this operator is positive definite,
+ meaning the real part of all eigenvalues is positive. We do not require
+ the operator to be self-adjoint to be positive-definite. See:
+* `https`: //en.wikipedia.org/wiki/Positive-definite_matrix
+ #Extension_for_non_symmetric_matrices
+* `name`: A name for this `LinearOperator`. Default is the individual
+ operators names joined with `_o_`.
+
+##### Raises:
+
+
+* `TypeError`: If all operators do not have the same `dtype`.
+* `ValueError`: If `operators` is empty.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.add_to_tensor(x, name='add_to_tensor')` {#LinearOperatorComposition.add_to_tensor}
+
+Add matrix represented by this operator to `x`. Equivalent to `A + x`.
+
+##### Args:
+
+
+* `x`: `Tensor` with same `dtype` and shape broadcastable to `self.shape`.
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ A `Tensor` with broadcast shape and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.apply(x, adjoint=False, name='apply')` {#LinearOperatorComposition.apply}
+
+Transform `x` with left multiplication: `x --> Ax`.
+
+##### Args:
+
+
+* `x`: `Tensor` with compatible shape and same `dtype` as `self`.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, left multiply by the adjoint.
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ A `Tensor` with shape `[..., M, R]` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.assert_non_singular(name='assert_non_singular')` {#LinearOperatorComposition.assert_non_singular}
+
+Returns an `Op` that asserts this operator is non singular.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.assert_positive_definite(name='assert_positive_definite')` {#LinearOperatorComposition.assert_positive_definite}
+
+Returns an `Op` that asserts this operator is positive definite.
+
+Here, positive definite means the real part of all eigenvalues is positive.
+We do not require the operator to be self-adjoint.
+
+##### Args:
+
+
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ An `Op` that asserts this operator is positive definite.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.assert_self_adjoint(name='assert_self_adjoint')` {#LinearOperatorComposition.assert_self_adjoint}
+
+Returns an `Op` that asserts this operator is self-adjoint.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.batch_shape` {#LinearOperatorComposition.batch_shape}
+
+`TensorShape` of batch dimensions of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb])`, equivalent to `A.get_shape()[:-2]`
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.batch_shape_dynamic(name='batch_shape_dynamic')` {#LinearOperatorComposition.batch_shape_dynamic}
+
+Shape of batch dimensions of this operator, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb]`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.determinant(name='det')` {#LinearOperatorComposition.determinant}
+
+Determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.domain_dimension` {#LinearOperatorComposition.domain_dimension}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.domain_dimension_dynamic(name='domain_dimension_dynamic')` {#LinearOperatorComposition.domain_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.dtype` {#LinearOperatorComposition.dtype}
+
+The `DType` of `Tensor`s handled by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.graph_parents` {#LinearOperatorComposition.graph_parents}
+
+List of graph dependencies of this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.is_non_singular` {#LinearOperatorComposition.is_non_singular}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.is_positive_definite` {#LinearOperatorComposition.is_positive_definite}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.is_self_adjoint` {#LinearOperatorComposition.is_self_adjoint}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.log_abs_determinant(name='log_abs_det')` {#LinearOperatorComposition.log_abs_determinant}
+
+Log absolute value of determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.name` {#LinearOperatorComposition.name}
+
+Name prepended to all ops created by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.operators` {#LinearOperatorComposition.operators}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.range_dimension` {#LinearOperatorComposition.range_dimension}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.range_dimension_dynamic(name='range_dimension_dynamic')` {#LinearOperatorComposition.range_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.shape` {#LinearOperatorComposition.shape}
+
+`TensorShape` of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb, M, N])`, equivalent to `A.get_shape()`.
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.shape_dynamic(name='shape_dynamic')` {#LinearOperatorComposition.shape_dynamic}
+
+Shape of this `LinearOperator`, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb, M, N]`, equivalent to `tf.shape(A)`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.solve(rhs, adjoint=False, name='solve')` {#LinearOperatorComposition.solve}
+
+Solve `R` (batch) systems of equations exactly: `A X = rhs`.
+
+Examples:
+
+```python
+# Create an operator acting like a 10 x 2 x 2 matrix.
+operator = LinearOperator(...)
+operator.shape # = 10 x 2 x 2
+
+# Solve one linear system (R = 1) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 1
+X = operator.solve(RHS) # shape 10 x 2 x 1
+
+# Solve five linear systems (R = 5) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 5
+X = operator.solve(RHS)
+X[3, :, 2] # Solution to the linear system A[3, :, :] X = RHS[3, :, 2]
+```
+
+##### Args:
+
+
+* `rhs`: `Tensor` with same `dtype` as this operator and compatible shape.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, solve the system involving the adjoint
+ of this `LinearOperator`.
+* `name`: A name scope to use for ops added by this method.
+
+##### Returns:
+
+ `Tensor` with shape `[...,N, R]` and same `dtype` as `rhs`.
+
+##### Raises:
+
+
+* `ValueError`: If self.is_non_singular is False.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.tensor_rank` {#LinearOperatorComposition.tensor_rank}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ Python integer, or None if the tensor rank is undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.tensor_rank_dynamic(name='tensor_rank_dynamic')` {#LinearOperatorComposition.tensor_rank_dynamic}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`, determined at runtime.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorComposition.to_dense(name='to_dense')` {#LinearOperatorComposition.to_dense}
+
+Return a dense (batch) matrix representing this operator.
+
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.split_v.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.split_v.md
index f9f83750fa6..0c3da3c87e3 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.split_v.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.split_v.md
@@ -2,13 +2,13 @@
Splits a tensor into sub tensors.
-If num_or_size_splits is a scalar, `num_split`, then
-splits `value` along dimension `axis` into `num_split` smaller tensors.
-Requires that `num_split` evenly divide `value.shape[split_dim]`.
+If `num_or_size_splits` is a scalar, `num_split`, then splits `value` along
+dimension `axis` into `num_split` smaller tensors.
+Requires that `num_split` evenly divides `value.shape[axis]`.
-If num_or_size_splits is a tensor, then
-splits `value` into len(size_splits) pieces each the same size as the input
-except along dimension split_dim where the size is size_splits[i].
+If `num_or_size_splits` is a tensor, `size_splits`, then splits `value` into
+`len(size_splits)` pieces. The shape of the `i`-th piece has the same size as
+the `value` except along dimension `axis` where the size is `size_splits[i]`.
For example:
@@ -31,12 +31,12 @@ tf.shape(split0) ==> [5, 10]
* `num_or_size_splits`: Either an integer indicating the number of splits along
split_dim or a 1-D Tensor containing the sizes of each output tensor
along split_dim. If an integer then it must evenly divide
- value.shape[split_dim]; otherwise the sum of sizes along the split
- dimension must match that of the input.
+ `value.shape[axis]`; otherwise the sum of sizes along the split
+ dimension must match that of the `value`.
* `axis`: A 0-D `int32` `Tensor`. The dimension along which to split.
Must be in the range `[0, rank(value))`. Defaults to 0.
* `num`: Optional, used to specify the number of outputs when it cannot be
- inferred from the shape of size_splits.
+ inferred from the shape of `size_splits`.
* `name`: A name for the operation (optional).
##### Returns:
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.split.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.split.md
index 3b5479a922c..df602383610 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.split.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.split.md
@@ -2,8 +2,6 @@
DEPRECATED: use split_v; split_v rename to split happening soon.
-Splits a tensor into `num_split` tensors along one dimension.
-
Splits `value` along dimension `axis` into `num_or_size_splits` smaller
tensors. Requires that `num_or_size_splits` evenly divide `value.shape[axis]`.
@@ -43,5 +41,5 @@ tf.unpack(t, axis=axis)
##### Returns:
- `num_split` `Tensor` objects resulting from splitting `value`.
+ `num_or_size_splits` `Tensor` objects resulting from splitting `value`.
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.contrib.linalg.LinearOperatorMatrix.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.contrib.linalg.LinearOperatorMatrix.md
new file mode 100644
index 00000000000..40bb846034a
--- /dev/null
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.contrib.linalg.LinearOperatorMatrix.md
@@ -0,0 +1,469 @@
+`LinearOperator` that wraps a [batch] matrix.
+
+This operator wraps a [batch] matrix `A` (which is a `Tensor`) with shape
+`[B1,...,Bb, M, N]` for some `b >= 0`. The first `b` indices index a
+batch member. For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
+an `M x N` matrix.
+
+```python
+# Create a 2 x 2 linear operator.
+matrix = [[1., 2.], [3., 4.]]
+operator = LinearOperatorMatrix(matrix)
+
+operator.to_dense()
+==> [[1., 2.]
+ [3., 4.]]
+
+operator.shape
+==> [2, 2]
+
+operator.log_determinant()
+==> scalar Tensor
+
+x = ... Shape [2, 4] Tensor
+operator.apply(x)
+==> Shape [2, 4] Tensor
+
+# Create a [2, 3] batch of 4 x 4 linear operators.
+matrix = tf.random_normal(shape=[2, 3, 4, 4])
+operator = LinearOperatorMatrix(matrix)
+```
+
+#### Shape compatibility
+
+This operator acts on [batch] matrix with compatible shape.
+`x` is a batch matrix with compatible shape for `apply` and `solve` if
+
+```
+operator.shape = [B1,...,Bb] + [M, N], with b >= 0
+x.shape = [B1,...,Bb] + [N, R], with R >= 0.
+```
+
+#### Performance
+
+`LinearOperatorMatrix` has exactly the same performance as would be achieved
+by using standard `TensorFlow` matrix ops. Intelligent choices are made
+based on the following initialization hints.
+
+* If `dtype` is real, and `is_self_adjoint` and `is_positive_definite`, a
+ Cholesky factorization is used for the determinant and solve.
+
+In all cases, suppose `operator` is a `LinearOperatorMatrix` of shape
+`[M, N]`, and `x.shape = [N, R]`. Then
+
+* `operator.apply(x)` is `O(M * N * R)`.
+* If `M=N`, `operator.solve(x)` is `O(N^3 * R)`.
+* If `M=N`, `operator.determinant()` is `O(N^3)`.
+
+If instead `operator` and `x` have shape `[B1,...,Bb, M, N]` and
+`[B1,...,Bb, N, R]`, every operation increases in complexity by `B1*...*Bb`.
+
+#### Matrix property hints
+
+This `LinearOperator` is initialized with boolean flags of the form `is_X`,
+for `X = non_singular, self_adjoint, positive_definite`.
+These have the following meaning
+* If `is_X == True`, callers should expect the operator to have the
+ property `X`. This is a promise that should be fulfilled, but is *not* a
+ runtime assert. For example, finite floating point precision may result
+ in these promises being violated.
+* If `is_X == False`, callers should expect the operator to not have `X`.
+* If `is_X == None` (the default), callers should have no expectation either
+ way.
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.__init__(matrix, is_non_singular=None, is_self_adjoint=None, is_positive_definite=None, name='LinearOperatorMatrix')` {#LinearOperatorMatrix.__init__}
+
+Initialize a `LinearOperatorMatrix`.
+
+##### Args:
+
+
+* `matrix`: Shape `[B1,...,Bb, M, N]` with `b >= 0`, `M, N >= 0`.
+ Allowed dtypes: `float32`, `float64`, `complex64`, `complex128`.
+* `is_non_singular`: Expect that this operator is non-singular.
+* `is_self_adjoint`: Expect that this operator is equal to its hermitian
+ transpose.
+* `is_positive_definite`: Expect that this operator is positive definite,
+ meaning the real part of all eigenvalues is positive. We do not require
+ the operator to be self-adjoint to be positive-definite. See:
+* `https`: //en.wikipedia.org/wiki/Positive-definite_matrix
+ #Extension_for_non_symmetric_matrices
+* `name`: A name for this `LinearOperator`.
+
+##### Raises:
+
+
+* `TypeError`: If `diag.dtype` is not an allowed type.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.add_to_tensor(x, name='add_to_tensor')` {#LinearOperatorMatrix.add_to_tensor}
+
+Add matrix represented by this operator to `x`. Equivalent to `A + x`.
+
+##### Args:
+
+
+* `x`: `Tensor` with same `dtype` and shape broadcastable to `self.shape`.
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ A `Tensor` with broadcast shape and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.apply(x, adjoint=False, name='apply')` {#LinearOperatorMatrix.apply}
+
+Transform `x` with left multiplication: `x --> Ax`.
+
+##### Args:
+
+
+* `x`: `Tensor` with compatible shape and same `dtype` as `self`.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, left multiply by the adjoint.
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ A `Tensor` with shape `[..., M, R]` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.assert_non_singular(name='assert_non_singular')` {#LinearOperatorMatrix.assert_non_singular}
+
+Returns an `Op` that asserts this operator is non singular.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.assert_positive_definite(name='assert_positive_definite')` {#LinearOperatorMatrix.assert_positive_definite}
+
+Returns an `Op` that asserts this operator is positive definite.
+
+Here, positive definite means the real part of all eigenvalues is positive.
+We do not require the operator to be self-adjoint.
+
+##### Args:
+
+
+* `name`: A name to give this `Op`.
+
+##### Returns:
+
+ An `Op` that asserts this operator is positive definite.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.assert_self_adjoint(name='assert_self_adjoint')` {#LinearOperatorMatrix.assert_self_adjoint}
+
+Returns an `Op` that asserts this operator is self-adjoint.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.batch_shape` {#LinearOperatorMatrix.batch_shape}
+
+`TensorShape` of batch dimensions of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb])`, equivalent to `A.get_shape()[:-2]`
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.batch_shape_dynamic(name='batch_shape_dynamic')` {#LinearOperatorMatrix.batch_shape_dynamic}
+
+Shape of batch dimensions of this operator, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb]`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.determinant(name='det')` {#LinearOperatorMatrix.determinant}
+
+Determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.domain_dimension` {#LinearOperatorMatrix.domain_dimension}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.domain_dimension_dynamic(name='domain_dimension_dynamic')` {#LinearOperatorMatrix.domain_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the domain of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `N`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.dtype` {#LinearOperatorMatrix.dtype}
+
+The `DType` of `Tensor`s handled by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.graph_parents` {#LinearOperatorMatrix.graph_parents}
+
+List of graph dependencies of this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.is_non_singular` {#LinearOperatorMatrix.is_non_singular}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.is_positive_definite` {#LinearOperatorMatrix.is_positive_definite}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.is_self_adjoint` {#LinearOperatorMatrix.is_self_adjoint}
+
+
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.log_abs_determinant(name='log_abs_det')` {#LinearOperatorMatrix.log_abs_determinant}
+
+Log absolute value of determinant for every batch member.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `Tensor` with shape `self.batch_shape` and same `dtype` as `self`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.name` {#LinearOperatorMatrix.name}
+
+Name prepended to all ops created by this `LinearOperator`.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.range_dimension` {#LinearOperatorMatrix.range_dimension}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Returns:
+
+ `Dimension` object.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.range_dimension_dynamic(name='range_dimension_dynamic')` {#LinearOperatorMatrix.range_dimension_dynamic}
+
+Dimension (in the sense of vector spaces) of the range of this operator.
+
+Determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `M`.
+
+##### Args:
+
+
+* `name`: A name for this `Op`.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.shape` {#LinearOperatorMatrix.shape}
+
+`TensorShape` of this `LinearOperator`.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns
+`TensorShape([B1,...,Bb, M, N])`, equivalent to `A.get_shape()`.
+
+##### Returns:
+
+ `TensorShape`, statically determined, may be undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.shape_dynamic(name='shape_dynamic')` {#LinearOperatorMatrix.shape_dynamic}
+
+Shape of this `LinearOperator`, determined at runtime.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns a `Tensor` holding
+`[B1,...,Bb, M, N]`, equivalent to `tf.shape(A)`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.solve(rhs, adjoint=False, name='solve')` {#LinearOperatorMatrix.solve}
+
+Solve `R` (batch) systems of equations exactly: `A X = rhs`.
+
+Examples:
+
+```python
+# Create an operator acting like a 10 x 2 x 2 matrix.
+operator = LinearOperator(...)
+operator.shape # = 10 x 2 x 2
+
+# Solve one linear system (R = 1) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 1
+X = operator.solve(RHS) # shape 10 x 2 x 1
+
+# Solve five linear systems (R = 5) for every member of the length 10 batch.
+RHS = ... # shape 10 x 2 x 5
+X = operator.solve(RHS)
+X[3, :, 2] # Solution to the linear system A[3, :, :] X = RHS[3, :, 2]
+```
+
+##### Args:
+
+
+* `rhs`: `Tensor` with same `dtype` as this operator and compatible shape.
+ See class docstring for definition of compatibility.
+* `adjoint`: Python `bool`. If `True`, solve the system involving the adjoint
+ of this `LinearOperator`.
+* `name`: A name scope to use for ops added by this method.
+
+##### Returns:
+
+ `Tensor` with shape `[...,N, R]` and same `dtype` as `rhs`.
+
+##### Raises:
+
+
+* `ValueError`: If self.is_non_singular is False.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.tensor_rank` {#LinearOperatorMatrix.tensor_rank}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ Python integer, or None if the tensor rank is undefined.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.tensor_rank_dynamic(name='tensor_rank_dynamic')` {#LinearOperatorMatrix.tensor_rank_dynamic}
+
+Rank (in the sense of tensors) of matrix corresponding to this operator.
+
+If this operator acts like the batch matrix `A` with
+`A.shape = [B1,...,Bb, M, N]`, then this returns `b + 2`.
+
+##### Args:
+
+
+* `name`: A name for this `Op.
+
+##### Returns:
+
+ `int32` `Tensor`, determined at runtime.
+
+
+- - -
+
+#### `tf.contrib.linalg.LinearOperatorMatrix.to_dense(name='to_dense')` {#LinearOperatorMatrix.to_dense}
+
+Return a dense (batch) matrix representing this operator.
+
+
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.contrib.linalg.LinearOperatorTriL.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.contrib.linalg.LinearOperatorTriL.md
index 1351773a3c2..5454b65f267 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.contrib.linalg.LinearOperatorTriL.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.contrib.linalg.LinearOperatorTriL.md
@@ -1,6 +1,6 @@
`LinearOperator` acting like a [batch] square lower triangular matrix.
-This operator acts like a [batch] matrix `A` with shape
+This operator acts like a [batch] lower triangular matrix `A` with shape
`[B1,...,Bb, N, N]` for some `b >= 0`. The first `b` indices index a
batch member. For every batch index `(i1,...,ib)`, `A[i1,...,ib, : :]` is
an `N x N` matrix.
@@ -31,16 +31,9 @@ operator.apply(x)
# Create a [2, 3] batch of 4 x 4 linear operators.
tril = tf.random_normal(shape=[2, 3, 4, 4])
operator = LinearOperatorTriL(tril)
-
-# Create a shape [2, 1, 4, 2] vector. Note that this shape is compatible
-# since the batch dimensions, [2, 1], are brodcast to
-# operator.batch_shape = [2, 3].
-y = tf.random_normal(shape=[2, 1, 4, 2])
-x = operator.solve(y)
-==> operator.apply(x) = y
```
-### Shape compatibility
+#### Shape compatibility
This operator acts on [batch] matrix with compatible shape.
`x` is a batch matrix with compatible shape for `apply` and `solve` if
@@ -50,7 +43,7 @@ operator.shape = [B1,...,Bb] + [N, N], with b >= 0
x.shape = [B1,...,Bb] + [N, R], with R >= 0.
```
-### Performance
+#### Performance
Suppose `operator` is a `LinearOperatorTriL` of shape `[N, N]`,
and `x.shape = [N, R]`. Then
@@ -62,10 +55,10 @@ and `x.shape = [N, R]`. Then
If instead `operator` and `x` have shape `[B1,...,Bb, N, N]` and
`[B1,...,Bb, N, R]`, every operation increases in complexity by `B1*...*Bb`.
-### Matrix property hints
+#### Matrix property hints
This `LinearOperator` is initialized with boolean flags of the form `is_X`,
-for `X = non_singular, self_adjoint` etc...
+for `X = non_singular, self_adjoint, positive_definite`.
These have the following meaning
* If `is_X == True`, callers should expect the operator to have the
property `X`. This is a promise that should be fulfilled, but is *not* a
@@ -237,8 +230,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -331,8 +323,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.linalg.LinearOperator.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.linalg.LinearOperator.md
index eb8a2005583..a07c373774e 100644
--- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.linalg.LinearOperator.md
+++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.contrib.linalg.LinearOperator.md
@@ -7,7 +7,7 @@ Subclasses of `LinearOperator` provide a access to common methods on a
* Operators that take advantage of special structure, while providing a
consistent API to users.
-### Subclassing
+#### Subclassing
To enable a public method, subclasses should implement the leading-underscore
version of the method. The argument signature should be identical except for
@@ -15,7 +15,7 @@ the omission of `name="..."`. For example, to enable
`apply(x, adjoint=False, name="apply")` a subclass should implement
`_apply(x, adjoint=False)`.
-### Performance contract
+#### Performance contract
Subclasses should implement a method only if it can be done with a reasonable
performance increase over generic dense operations, either in time, parallel
@@ -27,7 +27,7 @@ Class docstrings should contain an explanation of computational complexity.
Since this is a high-performance library, attention should be paid to detail,
and explanations can include constants as well as Big-O notation.
-### Shape compatibility
+#### Shape compatibility
`LinearOperator` sub classes should operate on a [batch] matrix with
compatible shape. Class docstrings should define what is meant by compatible
@@ -49,7 +49,7 @@ operator.shape = [B1,...,Bb] + [M, N], b >= 0,
rhs.shape = [B1,...,Bb] + [M, R]
```
-### Example docstring for subclasses.
+#### Example docstring for subclasses.
This operator acts like a (batch) matrix `A` with shape
`[B1,...,Bb, M, N]` for some `b >= 0`. The first `b` indices index a
@@ -76,19 +76,19 @@ operator.apply(x)
==> Shape [2, 4, 5] Tensor
```
-### Shape compatibility
+#### Shape compatibility
This operator acts on batch matrices with compatible shape.
FILL IN WHAT IS MEANT BY COMPATIBLE SHAPE
-### Performance
+#### Performance
FILL THIS IN
-### Matrix property hints
+#### Matrix property hints
This `LinearOperator` is initialized with boolean flags of the form `is_X`,
-for `X = non_singular, self_adjoint` etc...
+for `X = non_singular, self_adjoint, positive_definite`.
These have the following meaning
* If `is_X == True`, callers should expect the operator to have the
property `X`. This is a promise that should be fulfilled, but is *not* a
@@ -260,8 +260,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
@@ -354,8 +353,7 @@ If this operator acts like the batch matrix `A` with
##### Returns:
- Python integer if vector space dimension can be determined statically,
- otherwise `None`.
+ `Dimension` object.
- - -
diff --git a/tensorflow/g3doc/api_docs/python/index.md b/tensorflow/g3doc/api_docs/python/index.md
index 859338b220e..690c92f8df4 100644
--- a/tensorflow/g3doc/api_docs/python/index.md
+++ b/tensorflow/g3doc/api_docs/python/index.md
@@ -1017,7 +1017,9 @@
* **[Linear Algebra (contrib)](../../api_docs/python/contrib.linalg.md)**:
* [`LinearOperator`](../../api_docs/python/contrib.linalg.md#LinearOperator)
+ * [`LinearOperatorComposition`](../../api_docs/python/contrib.linalg.md#LinearOperatorComposition)
* [`LinearOperatorDiag`](../../api_docs/python/contrib.linalg.md#LinearOperatorDiag)
+ * [`LinearOperatorMatrix`](../../api_docs/python/contrib.linalg.md#LinearOperatorMatrix)
* [`LinearOperatorTriL`](../../api_docs/python/contrib.linalg.md#LinearOperatorTriL)
* **[Losses (contrib)](../../api_docs/python/contrib.losses.md)**: