annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/doc/broadcasting.py @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2a2c65a20a8b
children
rev   line source
Chris@87 1 """
Chris@87 2 ========================
Chris@87 3 Broadcasting over arrays
Chris@87 4 ========================
Chris@87 5
Chris@87 6 The term broadcasting describes how numpy treats arrays with different
Chris@87 7 shapes during arithmetic operations. Subject to certain constraints,
Chris@87 8 the smaller array is "broadcast" across the larger array so that they
Chris@87 9 have compatible shapes. Broadcasting provides a means of vectorizing
Chris@87 10 array operations so that looping occurs in C instead of Python. It does
Chris@87 11 this without making needless copies of data and usually leads to
Chris@87 12 efficient algorithm implementations. There are, however, cases where
Chris@87 13 broadcasting is a bad idea because it leads to inefficient use of memory
Chris@87 14 that slows computation.
Chris@87 15
Chris@87 16 NumPy operations are usually done on pairs of arrays on an
Chris@87 17 element-by-element basis. In the simplest case, the two arrays must
Chris@87 18 have exactly the same shape, as in the following example:
Chris@87 19
Chris@87 20 >>> a = np.array([1.0, 2.0, 3.0])
Chris@87 21 >>> b = np.array([2.0, 2.0, 2.0])
Chris@87 22 >>> a * b
Chris@87 23 array([ 2., 4., 6.])
Chris@87 24
Chris@87 25 NumPy's broadcasting rule relaxes this constraint when the arrays'
Chris@87 26 shapes meet certain constraints. The simplest broadcasting example occurs
Chris@87 27 when an array and a scalar value are combined in an operation:
Chris@87 28
Chris@87 29 >>> a = np.array([1.0, 2.0, 3.0])
Chris@87 30 >>> b = 2.0
Chris@87 31 >>> a * b
Chris@87 32 array([ 2., 4., 6.])
Chris@87 33
Chris@87 34 The result is equivalent to the previous example where ``b`` was an array.
Chris@87 35 We can think of the scalar ``b`` being *stretched* during the arithmetic
Chris@87 36 operation into an array with the same shape as ``a``. The new elements in
Chris@87 37 ``b`` are simply copies of the original scalar. The stretching analogy is
Chris@87 38 only conceptual. NumPy is smart enough to use the original scalar value
Chris@87 39 without actually making copies, so that broadcasting operations are as
Chris@87 40 memory and computationally efficient as possible.
Chris@87 41
Chris@87 42 The code in the second example is more efficient than that in the first
Chris@87 43 because broadcasting moves less memory around during the multiplication
Chris@87 44 (``b`` is a scalar rather than an array).
Chris@87 45
Chris@87 46 General Broadcasting Rules
Chris@87 47 ==========================
Chris@87 48 When operating on two arrays, NumPy compares their shapes element-wise.
Chris@87 49 It starts with the trailing dimensions, and works its way forward. Two
Chris@87 50 dimensions are compatible when
Chris@87 51
Chris@87 52 1) they are equal, or
Chris@87 53 2) one of them is 1
Chris@87 54
Chris@87 55 If these conditions are not met, a
Chris@87 56 ``ValueError: frames are not aligned`` exception is thrown, indicating that
Chris@87 57 the arrays have incompatible shapes. The size of the resulting array
Chris@87 58 is the maximum size along each dimension of the input arrays.
Chris@87 59
Chris@87 60 Arrays do not need to have the same *number* of dimensions. For example,
Chris@87 61 if you have a ``256x256x3`` array of RGB values, and you want to scale
Chris@87 62 each color in the image by a different value, you can multiply the image
Chris@87 63 by a one-dimensional array with 3 values. Lining up the sizes of the
Chris@87 64 trailing axes of these arrays according to the broadcast rules, shows that
Chris@87 65 they are compatible::
Chris@87 66
Chris@87 67 Image (3d array): 256 x 256 x 3
Chris@87 68 Scale (1d array): 3
Chris@87 69 Result (3d array): 256 x 256 x 3
Chris@87 70
Chris@87 71 When either of the dimensions compared is one, the other is
Chris@87 72 used. In other words, dimensions with size 1 are stretched or "copied"
Chris@87 73 to match the other.
Chris@87 74
Chris@87 75 In the following example, both the ``A`` and ``B`` arrays have axes with
Chris@87 76 length one that are expanded to a larger size during the broadcast
Chris@87 77 operation::
Chris@87 78
Chris@87 79 A (4d array): 8 x 1 x 6 x 1
Chris@87 80 B (3d array): 7 x 1 x 5
Chris@87 81 Result (4d array): 8 x 7 x 6 x 5
Chris@87 82
Chris@87 83 Here are some more examples::
Chris@87 84
Chris@87 85 A (2d array): 5 x 4
Chris@87 86 B (1d array): 1
Chris@87 87 Result (2d array): 5 x 4
Chris@87 88
Chris@87 89 A (2d array): 5 x 4
Chris@87 90 B (1d array): 4
Chris@87 91 Result (2d array): 5 x 4
Chris@87 92
Chris@87 93 A (3d array): 15 x 3 x 5
Chris@87 94 B (3d array): 15 x 1 x 5
Chris@87 95 Result (3d array): 15 x 3 x 5
Chris@87 96
Chris@87 97 A (3d array): 15 x 3 x 5
Chris@87 98 B (2d array): 3 x 5
Chris@87 99 Result (3d array): 15 x 3 x 5
Chris@87 100
Chris@87 101 A (3d array): 15 x 3 x 5
Chris@87 102 B (2d array): 3 x 1
Chris@87 103 Result (3d array): 15 x 3 x 5
Chris@87 104
Chris@87 105 Here are examples of shapes that do not broadcast::
Chris@87 106
Chris@87 107 A (1d array): 3
Chris@87 108 B (1d array): 4 # trailing dimensions do not match
Chris@87 109
Chris@87 110 A (2d array): 2 x 1
Chris@87 111 B (3d array): 8 x 4 x 3 # second from last dimensions mismatched
Chris@87 112
Chris@87 113 An example of broadcasting in practice::
Chris@87 114
Chris@87 115 >>> x = np.arange(4)
Chris@87 116 >>> xx = x.reshape(4,1)
Chris@87 117 >>> y = np.ones(5)
Chris@87 118 >>> z = np.ones((3,4))
Chris@87 119
Chris@87 120 >>> x.shape
Chris@87 121 (4,)
Chris@87 122
Chris@87 123 >>> y.shape
Chris@87 124 (5,)
Chris@87 125
Chris@87 126 >>> x + y
Chris@87 127 <type 'exceptions.ValueError'>: shape mismatch: objects cannot be broadcast to a single shape
Chris@87 128
Chris@87 129 >>> xx.shape
Chris@87 130 (4, 1)
Chris@87 131
Chris@87 132 >>> y.shape
Chris@87 133 (5,)
Chris@87 134
Chris@87 135 >>> (xx + y).shape
Chris@87 136 (4, 5)
Chris@87 137
Chris@87 138 >>> xx + y
Chris@87 139 array([[ 1., 1., 1., 1., 1.],
Chris@87 140 [ 2., 2., 2., 2., 2.],
Chris@87 141 [ 3., 3., 3., 3., 3.],
Chris@87 142 [ 4., 4., 4., 4., 4.]])
Chris@87 143
Chris@87 144 >>> x.shape
Chris@87 145 (4,)
Chris@87 146
Chris@87 147 >>> z.shape
Chris@87 148 (3, 4)
Chris@87 149
Chris@87 150 >>> (x + z).shape
Chris@87 151 (3, 4)
Chris@87 152
Chris@87 153 >>> x + z
Chris@87 154 array([[ 1., 2., 3., 4.],
Chris@87 155 [ 1., 2., 3., 4.],
Chris@87 156 [ 1., 2., 3., 4.]])
Chris@87 157
Chris@87 158 Broadcasting provides a convenient way of taking the outer product (or
Chris@87 159 any other outer operation) of two arrays. The following example shows an
Chris@87 160 outer addition operation of two 1-d arrays::
Chris@87 161
Chris@87 162 >>> a = np.array([0.0, 10.0, 20.0, 30.0])
Chris@87 163 >>> b = np.array([1.0, 2.0, 3.0])
Chris@87 164 >>> a[:, np.newaxis] + b
Chris@87 165 array([[ 1., 2., 3.],
Chris@87 166 [ 11., 12., 13.],
Chris@87 167 [ 21., 22., 23.],
Chris@87 168 [ 31., 32., 33.]])
Chris@87 169
Chris@87 170 Here the ``newaxis`` index operator inserts a new axis into ``a``,
Chris@87 171 making it a two-dimensional ``4x1`` array. Combining the ``4x1`` array
Chris@87 172 with ``b``, which has shape ``(3,)``, yields a ``4x3`` array.
Chris@87 173
Chris@87 174 See `this article <http://wiki.scipy.org/EricsBroadcastingDoc>`_
Chris@87 175 for illustrations of broadcasting concepts.
Chris@87 176
Chris@87 177 """
Chris@87 178 from __future__ import division, absolute_import, print_function