On Fri, Jul 1, 2011 at 6:38 PM, Thomas K Gamble <tkgamble@windstream.net> wrote:
> On Thu, Jun 30, 2011 at 11:32 AM, Thomas K Gamble
>
> <tkgamble@windstream.net>wrote:
> > I'm trying to convert some IDL code to python/numpy and i'm having some
> > trouble understanding the rules for boradcasting during some operations.
> > example:
> >
> > given the following arrays:
> > a = array((2048,3577), dtype=float)
> > b = array((256,25088), dtype=float)
> > c = array((2048,3136), dtype=float)
> > d = array((2048,3136), dtype=float)
> >
> > do:
> > a = b * c + d
> >
> > In IDL, the computation is done without complaint and all array sizes are
> > preserved.  In ptyhon I get a value error concerning broadcasting.  I can
> > force it to work by taking slices, but the resulting size would be a =
> > (256x3136) rather than (2048x3577).  I admit that I don't understand IDL
> > (or
> > python to be honest) well enough to know how it handles this to be able
> > to replicate the result properly.  Does it only operate on the smallest
> > dimensions ignoring the larger indices leaving their values unchanged?
> > Can someone explain this to me?
>
> I don't see a problem
>
> In [1]: datetime64('now')
> Out[1]: numpy.datetime64('2011-07-01T07:18:35-0600')
>
> In [2]: a = array((2048, 3577), float)
>
> In [3]: b = array((256, 25088), float)
>
> In [4]: c = array((2048, 3136), float)
>
> In [5]: d = array((2048, 3136), float)
>
> In [6]: a = b*c + d
>
> In [7]: a
> Out[7]: array([   526336.,  78679104.])
>
> What is the '*' in your expression supposed to mean?

My apologies for the errors in my example.  It should have been:

a = numpy.ndarray((2048,3577), dtype=float)
b = numpy.ndarray((256,25088), dtype=float)
c = numpy.ndarray((2048,3136), dtype=float)
d = numpy.ndarray((2048,3136), dtype=float)

The numbers are the array dimensions.  Data values are not provided in the
example.


Ah, what that does in make (2,) arrays with the given elements and '*' and '+' are element-wise multiplication and addition. To get arrays with the dimensions you need something like

In [19]: a = numpy.zeros((2048,3577), dtype=float)

In [20]: b = numpy.zeros((256,25088), dtype=float)

In [21]: c = numpy.zeros((2048,3136), dtype=float)

In [22]: d = numpy.zeros((2048,3136), dtype=float)

However, broadcasting b and c won't work, it isn't enough that 256 divides 2048, 256 must actually equal 1, which you can omit since it is a leading index. Same with 3136 and 25088 except the one won't automagically be added.

So you can do things like

 In [24]: numpy.zeros((5,7))*numpy.zeros((7,))
Out[24]:
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]])

second array will be broadcast over the first.

Chuck