<div class="gmail_quote">On Wed, Jan 26, 2011 at 8:29 PM, Joshua Holbrook <span dir="ltr"><<a href="mailto:josh.holbrook@gmail.com">josh.holbrook@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">>><br>
>> The only disadvantage I see, is that choosing the axes to operate on<br>
>> in a program or function requires string manipulation.<br>
><br>
><br>
> One possibility would be for the Python exposure to accept lists or tuples<br>
> of integers.  The subscript 'ii' could be [(0,0)], and 'ij,jk->ik' could be<br>
> [(0,1), (1,2), (0,2)].  Internally it would convert this directly to a<br>
> C-string to pass to the API function.<br>
> -Mark<br>
><br>
<br>
</div>What if you made objects i, j, etc. such that i*j = (0, 1) and<br>
etcetera? Maybe you could generate them with something like (i, j, k)<br>
= einstein((1, 2, 3)) .<br>
<br>
Feel free to disregard me since I haven't really thought too hard<br>
about things and might not even really understand what the problem is<br>
*anyway*. I'm just trying to help brainstorm. :)<br></blockquote><div><br></div><div>No worries. :)  The problem is that someone will probably want to dynamically generate the axes to process in a loop, rather than having them hardcoded beforehand.  For example, generalizing the diag function as follows.  Within Python, creating lists and tuples is probably more natural.</div>
<div><br></div><div>-Mark</div><div><br></div><div><div>>>> def diagij(x, i, j):</div><div>...     ss = ""</div><div>...     so = ""</div><div>...     # should error check i, j</div><div>...     fill = ord('b')</div>
<div>...     for k in range(x.ndim):</div><div>...         if k in [i, j]:</div><div>...             ss += 'a'</div><div>...         else:</div><div>...             ss += chr(fill)</div><div>...             so += chr(fill)</div>
<div>...             fill += 1</div><div>...     ss += '->' + so + 'a'</div><div>...     return np.einsum(ss, x)</div><div>... </div><div>>>> x = np.arange(3*3*3).reshape(3,3,3)</div></div><div>
<div>>>> diagij(x, 0, 1)</div><div>array([[ 0, 12, 24],</div><div>       [ 1, 13, 25],</div><div>       [ 2, 14, 26]])</div><div><div><br></div><div>>>> [np.diag(x[:,:,i]) for i in range(3)]</div><div>[array([ 0, 12, 24]), array([ 1, 13, 25]), array([ 2, 14, 26])]</div>
</div><div><br></div><div>>>> diagij(x, 1, 2)</div><div>array([[ 0,  4,  8],</div><div>       [ 9, 13, 17],</div><div>       [18, 22, 26]])</div></div><div><br></div></div>