summaryrefslogtreecommitdiff
path: root/numpy/add_newdocs.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/add_newdocs.py')
-rw-r--r--numpy/add_newdocs.py317
1 files changed, 198 insertions, 119 deletions
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
index a39aebc0c..09cae54b1 100644
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -1453,7 +1453,7 @@ add_newdoc('numpy.core.multiarray', 'arange',
Values are generated within the half-open interval ``[start, stop)``
(in other words, the interval including `start` but excluding `stop`).
For integer arguments the function is equivalent to the Python built-in
- `range <http://docs.python.org/lib/built-in-funcs.html>`_ function,
+ `range <https://docs.python.org/library/functions.html#func-range>`_ function,
but returns an ndarray rather than a list.
When using a non-integer step, such as 0.1, the results will often not
@@ -2266,25 +2266,89 @@ add_newdoc('numpy.core', 'matmul',
""")
+add_newdoc('numpy.core', 'vdot',
+ """
+ vdot(a, b)
+
+ Return the dot product of two vectors.
+
+ The vdot(`a`, `b`) function handles complex numbers differently than
+ dot(`a`, `b`). If the first argument is complex the complex conjugate
+ of the first argument is used for the calculation of the dot product.
-add_newdoc('numpy.core', 'c_einsum',
+ Note that `vdot` handles multidimensional arrays differently than `dot`:
+ it does *not* perform a matrix product, but flattens input arguments
+ to 1-D vectors first. Consequently, it should only be used for vectors.
+
+ Parameters
+ ----------
+ a : array_like
+ If `a` is complex the complex conjugate is taken before calculation
+ of the dot product.
+ b : array_like
+ Second argument to the dot product.
+
+ Returns
+ -------
+ output : ndarray
+ Dot product of `a` and `b`. Can be an int, float, or
+ complex depending on the types of `a` and `b`.
+
+ See Also
+ --------
+ dot : Return the dot product without using the complex conjugate of the
+ first argument.
+
+ Examples
+ --------
+ >>> a = np.array([1+2j,3+4j])
+ >>> b = np.array([5+6j,7+8j])
+ >>> np.vdot(a, b)
+ (70-8j)
+ >>> np.vdot(b, a)
+ (70+8j)
+
+ Note that higher-dimensional arrays are flattened!
+
+ >>> a = np.array([[1, 4], [5, 6]])
+ >>> b = np.array([[4, 1], [2, 2]])
+ >>> np.vdot(a, b)
+ 30
+ >>> np.vdot(b, a)
+ 30
+ >>> 1*4 + 4*1 + 5*2 + 6*2
+ 30
+
+ """)
+
+add_newdoc('numpy.core.multiarray', 'c_einsum',
"""
- c_einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe')
+ c_einsum(subscripts, *operands, out=None, dtype=None, order='K',
+ casting='safe')
+
+ *This documentation shadows that of the native python implementation of the `einsum` function,
+ except all references and examples related to the `optimize` argument (v 0.12.0) have been removed.*
Evaluates the Einstein summation convention on the operands.
- Using the Einstein summation convention, many common multi-dimensional
- array operations can be represented in a simple fashion. This function
- provides a way to compute such summations. The best way to understand this
- function is to try the examples below, which show how many common NumPy
- functions can be implemented as calls to `einsum`.
+ Using the Einstein summation convention, many common multi-dimensional,
+ linear algebraic array operations can be represented in a simple fashion.
+ In *implicit* mode `einsum` computes these values.
+
+ In *explicit* mode, `einsum` provides further flexibility to compute
+ other array operations that might not be considered classical Einstein
+ summation operations, by disabling, or forcing summation over specified
+ subscript labels.
- This is the core C function.
+ See the notes and examples for clarification.
Parameters
----------
subscripts : str
- Specifies the subscripts for summation.
+ Specifies the subscripts for summation as comma separated list of
+ subscript labels. An implicit (classical Einstein summation)
+ calculation is performed unless the explicit indicator '->' is
+ included as well as subscript labels of the precise output form.
operands : list of array_like
These are the arrays for the operation.
out : ndarray, optional
@@ -2312,6 +2376,11 @@ add_newdoc('numpy.core', 'c_einsum',
* 'unsafe' means any data conversions may be done.
Default is 'safe'.
+ optimize : {False, True, 'greedy', 'optimal'}, optional
+ Controls if intermediate optimization should occur. No optimization
+ will occur if False and True will default to the 'greedy' algorithm.
+ Also accepts an explicit contraction list from the ``np.einsum_path``
+ function. See ``np.einsum_path`` for more details. Defaults to False.
Returns
-------
@@ -2320,56 +2389,86 @@ add_newdoc('numpy.core', 'c_einsum',
See Also
--------
- einsum, dot, inner, outer, tensordot
+ einsum_path, dot, inner, outer, tensordot, linalg.multi_dot
Notes
-----
.. versionadded:: 1.6.0
- The subscripts string is a comma-separated list of subscript labels,
- where each label refers to a dimension of the corresponding operand.
- Repeated subscripts labels in one operand take the diagonal. For example,
- ``np.einsum('ii', a)`` is equivalent to ``np.trace(a)``.
+ The Einstein summation convention can be used to compute
+ many multi-dimensional, linear algebraic array operations. `einsum`
+ provides a succinct way of representing these.
- Whenever a label is repeated, it is summed, so ``np.einsum('i,i', a, b)``
- is equivalent to ``np.inner(a,b)``. If a label appears only once,
- it is not summed, so ``np.einsum('i', a)`` produces a view of ``a``
- with no changes.
+ A non-exhaustive list of these operations,
+ which can be computed by `einsum`, is shown below along with examples:
- The order of labels in the output is by default alphabetical. This
- means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while
- ``np.einsum('ji', a)`` takes its transpose.
+ * Trace of an array, :py:func:`numpy.trace`.
+ * Return a diagonal, :py:func:`numpy.diag`.
+ * Array axis summations, :py:func:`numpy.sum`.
+ * Transpositions and permutations, :py:func:`numpy.transpose`.
+ * Matrix multiplication and dot product, :py:func:`numpy.matmul` :py:func:`numpy.dot`.
+ * Vector inner and outer products, :py:func:`numpy.inner` :py:func:`numpy.outer`.
+ * Broadcasting, element-wise and scalar multiplication, :py:func:`numpy.multiply`.
+ * Tensor contractions, :py:func:`numpy.tensordot`.
+ * Chained array operations, in efficient calculation order, :py:func:`numpy.einsum_path`.
- The output can be controlled by specifying output subscript labels
- as well. This specifies the label order, and allows summing to
- be disallowed or forced when desired. The call ``np.einsum('i->', a)``
- is like ``np.sum(a, axis=-1)``, and ``np.einsum('ii->i', a)``
- is like ``np.diag(a)``. The difference is that `einsum` does not
- allow broadcasting by default.
+ The subscripts string is a comma-separated list of subscript labels,
+ where each label refers to a dimension of the corresponding operand.
+ Whenever a label is repeated it is summed, so ``np.einsum('i,i', a, b)``
+ is equivalent to :py:func:`np.inner(a,b) <numpy.inner>`. If a label
+ appears only once, it is not summed, so ``np.einsum('i', a)`` produces a
+ view of ``a`` with no changes. A further example ``np.einsum('ij,jk', a, b)``
+ describes traditional matrix multiplication and is equivalent to
+ :py:func:`np.matmul(a,b) <numpy.matmul>`. Repeated subscript labels in one
+ operand take the diagonal. For example, ``np.einsum('ii', a)`` is equivalent
+ to :py:func:`np.trace(a) <numpy.trace>`.
+
+ In *implicit mode*, the chosen subscripts are important
+ since the axes of the output are reordered alphabetically. This
+ means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while
+ ``np.einsum('ji', a)`` takes its transpose. Additionally,
+ ``np.einsum('ij,jk', a, b)`` returns a matrix multiplication, while,
+ ``np.einsum('ij,jh', a, b)`` returns the transpose of the
+ multiplication since subscript 'h' precedes subscript 'i'.
+
+ In *explicit mode* the output can be directly controlled by
+ specifying output subscript labels. This requires the
+ identifier '->' as well as the list of output subscript labels.
+ This feature increases the flexibility of the function since
+ summing can be disabled or forced when required. The call
+ ``np.einsum('i->', a)`` is like :py:func:`np.sum(a, axis=-1) <numpy.sum>`,
+ and ``np.einsum('ii->i', a)`` is like :py:func:`np.diag(a) <numpy.diag>`.
+ The difference is that `einsum` does not allow broadcasting by default.
+ Additionally ``np.einsum('ij,jh->ih', a, b)`` directly specifies the
+ order of the output subscript labels and therefore returns matrix
+ multiplication, unlike the example above in implicit mode.
To enable and control broadcasting, use an ellipsis. Default
NumPy-style broadcasting is done by adding an ellipsis
to the left of each term, like ``np.einsum('...ii->...i', a)``.
To take the trace along the first and last axes,
you can do ``np.einsum('i...i', a)``, or to do a matrix-matrix
- product with the left-most indices instead of rightmost, you can do
+ product with the left-most indices instead of rightmost, one can do
``np.einsum('ij...,jk...->ik...', a, b)``.
When there is only one operand, no axes are summed, and no output
parameter is provided, a view into the operand is returned instead
of a new array. Thus, taking the diagonal as ``np.einsum('ii->i', a)``
- produces a view.
+ produces a view (changed in version 1.10.0).
- An alternative way to provide the subscripts and operands is as
- ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``. The examples
- below have corresponding `einsum` calls with the two parameter methods.
+ `einsum` also provides an alternative way to provide the subscripts
+ and operands as ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``.
+ If the output shape is not provided in this format `einsum` will be
+ calculated in implicit mode, otherwise it will be performed explicitly.
+ The examples below have corresponding `einsum` calls with the two
+ parameter methods.
.. versionadded:: 1.10.0
Views returned from einsum are now writeable whenever the input array
is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now
- have the same effect as ``np.swapaxes(a, 0, 2)`` and
- ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal
+ have the same effect as :py:func:`np.swapaxes(a, 0, 2) <numpy.swapaxes>`
+ and ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal
of a 2D array.
Examples
@@ -2378,6 +2477,8 @@ add_newdoc('numpy.core', 'c_einsum',
>>> b = np.arange(5)
>>> c = np.arange(6).reshape(2,3)
+ Trace of a matrix:
+
>>> np.einsum('ii', a)
60
>>> np.einsum(a, [0,0])
@@ -2385,6 +2486,8 @@ add_newdoc('numpy.core', 'c_einsum',
>>> np.trace(a)
60
+ Extract the diagonal (requires explicit form):
+
>>> np.einsum('ii->i', a)
array([ 0, 6, 12, 18, 24])
>>> np.einsum(a, [0,0], [0])
@@ -2392,31 +2495,69 @@ add_newdoc('numpy.core', 'c_einsum',
>>> np.diag(a)
array([ 0, 6, 12, 18, 24])
- >>> np.einsum('ij,j', a, b)
- array([ 30, 80, 130, 180, 230])
- >>> np.einsum(a, [0,1], b, [1])
- array([ 30, 80, 130, 180, 230])
- >>> np.dot(a, b)
- array([ 30, 80, 130, 180, 230])
- >>> np.einsum('...j,j', a, b)
- array([ 30, 80, 130, 180, 230])
+ Sum over an axis (requires explicit form):
+
+ >>> np.einsum('ij->i', a)
+ array([ 10, 35, 60, 85, 110])
+ >>> np.einsum(a, [0,1], [0])
+ array([ 10, 35, 60, 85, 110])
+ >>> np.sum(a, axis=1)
+ array([ 10, 35, 60, 85, 110])
+
+ For higher dimensional arrays summing a single axis can be done with ellipsis:
+
+ >>> np.einsum('...j->...', a)
+ array([ 10, 35, 60, 85, 110])
+ >>> np.einsum(a, [Ellipsis,1], [Ellipsis])
+ array([ 10, 35, 60, 85, 110])
+
+ Compute a matrix transpose, or reorder any number of axes:
>>> np.einsum('ji', c)
array([[0, 3],
[1, 4],
[2, 5]])
+ >>> np.einsum('ij->ji', c)
+ array([[0, 3],
+ [1, 4],
+ [2, 5]])
>>> np.einsum(c, [1,0])
array([[0, 3],
[1, 4],
[2, 5]])
- >>> c.T
+ >>> np.transpose(c)
array([[0, 3],
[1, 4],
[2, 5]])
+ Vector inner products:
+
+ >>> np.einsum('i,i', b, b)
+ 30
+ >>> np.einsum(b, [0], b, [0])
+ 30
+ >>> np.inner(b,b)
+ 30
+
+ Matrix vector multiplication:
+
+ >>> np.einsum('ij,j', a, b)
+ array([ 30, 80, 130, 180, 230])
+ >>> np.einsum(a, [0,1], b, [1])
+ array([ 30, 80, 130, 180, 230])
+ >>> np.dot(a, b)
+ array([ 30, 80, 130, 180, 230])
+ >>> np.einsum('...j,j', a, b)
+ array([ 30, 80, 130, 180, 230])
+
+ Broadcasting and scalar multiplication:
+
>>> np.einsum('..., ...', 3, c)
array([[ 0, 3, 6],
[ 9, 12, 15]])
+ >>> np.einsum(',ij', 3, c)
+ array([[ 0, 3, 6],
+ [ 9, 12, 15]])
>>> np.einsum(3, [Ellipsis], c, [Ellipsis])
array([[ 0, 3, 6],
[ 9, 12, 15]])
@@ -2424,12 +2565,7 @@ add_newdoc('numpy.core', 'c_einsum',
array([[ 0, 3, 6],
[ 9, 12, 15]])
- >>> np.einsum('i,i', b, b)
- 30
- >>> np.einsum(b, [0], b, [0])
- 30
- >>> np.inner(b,b)
- 30
+ Vector outer product:
>>> np.einsum('i,j', np.arange(2)+1, b)
array([[0, 1, 2, 3, 4],
@@ -2441,12 +2577,7 @@ add_newdoc('numpy.core', 'c_einsum',
array([[0, 1, 2, 3, 4],
[0, 2, 4, 6, 8]])
- >>> np.einsum('i...->...', a)
- array([50, 55, 60, 65, 70])
- >>> np.einsum(a, [0,Ellipsis], [Ellipsis])
- array([50, 55, 60, 65, 70])
- >>> np.sum(a, axis=0)
- array([50, 55, 60, 65, 70])
+ Tensor contraction:
>>> a = np.arange(60.).reshape(3,4,5)
>>> b = np.arange(24.).reshape(4,3,2)
@@ -2469,6 +2600,17 @@ add_newdoc('numpy.core', 'c_einsum',
[ 4796., 5162.],
[ 4928., 5306.]])
+ Writeable returned arrays (since version 1.10.0):
+
+ >>> a = np.zeros((3, 3))
+ >>> np.einsum('ii->i', a)[:] = 1
+ >>> a
+ array([[ 1., 0., 0.],
+ [ 0., 1., 0.],
+ [ 0., 0., 1.]])
+
+ Example of ellipsis use:
+
>>> a = np.arange(6).reshape((3,2))
>>> b = np.arange(12).reshape((4,3))
>>> np.einsum('ki,jk->ij', a, b)
@@ -2481,69 +2623,6 @@ add_newdoc('numpy.core', 'c_einsum',
array([[10, 28, 46, 64],
[13, 40, 67, 94]])
- >>> # since version 1.10.0
- >>> a = np.zeros((3, 3))
- >>> np.einsum('ii->i', a)[:] = 1
- >>> a
- array([[ 1., 0., 0.],
- [ 0., 1., 0.],
- [ 0., 0., 1.]])
-
- """)
-
-add_newdoc('numpy.core', 'vdot',
- """
- vdot(a, b)
-
- Return the dot product of two vectors.
-
- The vdot(`a`, `b`) function handles complex numbers differently than
- dot(`a`, `b`). If the first argument is complex the complex conjugate
- of the first argument is used for the calculation of the dot product.
-
- Note that `vdot` handles multidimensional arrays differently than `dot`:
- it does *not* perform a matrix product, but flattens input arguments
- to 1-D vectors first. Consequently, it should only be used for vectors.
-
- Parameters
- ----------
- a : array_like
- If `a` is complex the complex conjugate is taken before calculation
- of the dot product.
- b : array_like
- Second argument to the dot product.
-
- Returns
- -------
- output : ndarray
- Dot product of `a` and `b`. Can be an int, float, or
- complex depending on the types of `a` and `b`.
-
- See Also
- --------
- dot : Return the dot product without using the complex conjugate of the
- first argument.
-
- Examples
- --------
- >>> a = np.array([1+2j,3+4j])
- >>> b = np.array([5+6j,7+8j])
- >>> np.vdot(a, b)
- (70-8j)
- >>> np.vdot(b, a)
- (70+8j)
-
- Note that higher-dimensional arrays are flattened!
-
- >>> a = np.array([[1, 4], [5, 6]])
- >>> b = np.array([[4, 1], [2, 2]])
- >>> np.vdot(a, b)
- 30
- >>> np.vdot(b, a)
- 30
- >>> 1*4 + 4*1 + 5*2 + 6*2
- 30
-
""")