Solve the tensor equation ``a x = b`` for x. It is assumed that all indices of `x` are summed over in the product, together with the rightmost indices of `a`, as is done in, for example, ``tensordot(a, x, axes=x.ndim)``. Parameters ---------- a : array_like Coe
(a, b, axes=None)
| 247 | |
| 248 | @array_function_dispatch(_tensorsolve_dispatcher) |
| 249 | def tensorsolve(a, b, axes=None): |
| 250 | """ |
| 251 | Solve the tensor equation ``a x = b`` for x. |
| 252 | |
| 253 | It is assumed that all indices of `x` are summed over in the product, |
| 254 | together with the rightmost indices of `a`, as is done in, for example, |
| 255 | ``tensordot(a, x, axes=x.ndim)``. |
| 256 | |
| 257 | Parameters |
| 258 | ---------- |
| 259 | a : array_like |
| 260 | Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals |
| 261 | the shape of that sub-tensor of `a` consisting of the appropriate |
| 262 | number of its rightmost indices, and must be such that |
| 263 | ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be |
| 264 | 'square'). |
| 265 | b : array_like |
| 266 | Right-hand tensor, which can be of any shape. |
| 267 | axes : tuple of ints, optional |
| 268 | Axes in `a` to reorder to the right, before inversion. |
| 269 | If None (default), no reordering is done. |
| 270 | |
| 271 | Returns |
| 272 | ------- |
| 273 | x : ndarray, shape Q |
| 274 | |
| 275 | Raises |
| 276 | ------ |
| 277 | LinAlgError |
| 278 | If `a` is singular or not 'square' (in the above sense). |
| 279 | |
| 280 | See Also |
| 281 | -------- |
| 282 | numpy.tensordot, tensorinv, numpy.einsum |
| 283 | |
| 284 | Examples |
| 285 | -------- |
| 286 | >>> a = np.eye(2*3*4) |
| 287 | >>> a.shape = (2*3, 4, 2, 3, 4) |
| 288 | >>> b = np.random.randn(2*3, 4) |
| 289 | >>> x = np.linalg.tensorsolve(a, b) |
| 290 | >>> x.shape |
| 291 | (2, 3, 4) |
| 292 | >>> np.allclose(np.tensordot(a, x, axes=3), b) |
| 293 | True |
| 294 | |
| 295 | """ |
| 296 | a, wrap = _makearray(a) |
| 297 | b = asarray(b) |
| 298 | an = a.ndim |
| 299 | |
| 300 | if axes is not None: |
| 301 | allaxes = list(range(0, an)) |
| 302 | for k in axes: |
| 303 | allaxes.remove(k) |
| 304 | allaxes.insert(an, k) |
| 305 | a = a.transpose(allaxes) |
| 306 |
nothing calls this directly
no test coverage detected