python - Summing over ellipsis broadcast dimension in numpy.einsum -


in numpy, have array can either 2-d or 3-d, , reduce 2-d while squaring each element. tried , doesn't work:

a = np.random.rand(5, 3, 3) np.einsum('...ij,...ij->ij', a, a) 

it returns error:

valueerror: output has more dimensions subscripts given in einstein sum, no '...' ellipsis provided broadcast dimensions. 

i suppose einsum doesn't assume when ellipsis goes away in right hand side, want sum on ellipsis dimension(s), if exist. there "elegant" way (i.e. without checking number of dimensions , using if statement) tell want 3-d:

a = np.random.rand(5, 3, 3) np.einsum('aij,aij->ij', a, a) 

and 2-d?

a = np.random.rand(3, 3) np.einsum('ij,ij->ij', a, a) 

sometimes 'elegant' way handle variable dimensions use set of if tests, , hide them in function call. example @ np.atleast_3d; has 4way if/else clause. i'd recommend here, except adds dimension @ end, not start. if clauses using reshape not expensive (time wise), don't afraid use them. if find magical function, @ code; may surprised hidden.


ellipsis used dimensions 'go along ride', not ones want specific control. here want sum on initial dimension, need index explicitly:

in [161]: np.einsum('i...,i...',a,a) out[161]:  array([[ 1.26942035,  1.32052776,  1.74118617],        [ 1.59679765,  1.49331565,  2.04573002],        [ 2.29027005,  1.48351522,  1.36679208]]) in [162]: np.einsum('aij,aij->ij',a,a) out[162]:  array([[ 1.26942035,  1.32052776,  1.74118617],        [ 1.59679765,  1.49331565,  2.04573002],        [ 2.29027005,  1.48351522,  1.36679208]]) 

for 2d array:

in [165]: np.einsum('ij,ij->ij',a[0],a[0]) out[165]:  array([[ 0.20497776,  0.11632197,  0.65396968],        [ 0.0529767 ,  0.24723351,  0.27559647],        [ 0.62806525,  0.33081124,  0.57070406]]) in [166]: a[0]*a[0] out[166]:  array([[ 0.20497776,  0.11632197,  0.65396968],        [ 0.0529767 ,  0.24723351,  0.27559647],        [ 0.62806525,  0.33081124,  0.57070406]]) in [167]:  in [167]: np.einsum('...,...',a[0],a[0]) out[167]:  array([[ 0.20497776,  0.11632197,  0.65396968],        [ 0.0529767 ,  0.24723351,  0.27559647],        [ 0.62806525,  0.33081124,  0.57070406]]) 

i don't think can handle both cases 1 expression.

another way first sum

in [168]: (a*a).sum(axis=0) out[168]:  array([[ 1.26942035,  1.32052776,  1.74118617],        [ 1.59679765,  1.49331565,  2.04573002],        [ 2.29027005,  1.48351522,  1.36679208]]) 

i contributed patch fixed handling of ellipsis, couple of years ago. details aren't super fresh in mind. part of reverse engineered parsing string expression (the original compiled), , review code (or refer it), if need more definitive answer.


in [172]: np.einsum('...ij,...ij->ij',a,a) --------------------------------------------------------------------------- valueerror                                traceback (most recent call last) <ipython-input-172-dfe39e268402> in <module>() ----> 1 np.einsum('...ij,...ij->ij',a,a)  valueerror: output has more dimensions subscripts given in   einstein sum, no '...' ellipsis provided broadcast   dimensions. in [173]: np.einsum('...ij,...ij->...ij',a,a).shape out[173]: (5, 3, 3) 

the error message says trying pass ... dimensions output, , can't - because output missing dimensions or .... in other words, not perform summation on ... dimensions. pass output unchanged (broadcasting rules apply).


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -