Hey Tim,

Yep, sure does.

For those who find this later (i.e. future me), here are a couple ways to 
replicate the example in the numpy docs using TensorOperations.jl:

using TensorOperations, IndexNotation

# NOTE: we build it inside-out and then permute to match numpy's row major
#       reshape with Julia's column major reshape.
a = permutedims(reshape(0:59.0, (5, 4, 3)), (3, 2, 1))

b = permutedims(reshape(0:23.0, (2, 3, 4)), (3, 2, 1))

# first method -- using IndexNotation
c1 = a[l"a,b,c"]*b[l"b,a,d"]

# second method -- calling tensorcontract
c2 = tensorcontract(a, ["a", "b", "c"], b, ["b", "a", "d"])

# third method -- using inlace operations
c3 = Array(Float64, 5, 2)
TensorOperations.tensorcontract!(1,a,["a", "b", "c"],'N',b,["b", "a", 
"d"],'N',0.0, c3,["c", "d"])

On Sunday, February 22, 2015 at 6:34:12 AM UTC-5, Tim Holy wrote:

Does TensorOperations.jl do what you want? 
>
> --Tim 
>
> On Sunday, February 22, 2015 12:32:34 AM Viral Shah wrote: 
> > Best to file an issue. 
> > 
> > -viral 
> > 
> > On Sunday, February 22, 2015 at 12:52:17 PM UTC+5:30, Spencer Lyon 
> wrote: 
> > > Bump on this thread. I need this functionality again... 
> > > 
> > > On Friday, December 6, 2013 at 11:04:44 AM UTC-5, Spencer Lyon wrote: 
> > >> I am working with tensors with more than 2 dimensions. I would like 
> to 
> > >> find a Julia equivalent to the numpy function tensordot. The 
> docstring 
> > >> for the function explains its use well, so I will just copy/paste it 
> > >> here: 
> > >> 
> > >> def tensordot(a, b, axes=2): 
> > >>     """ 
> > >>     Compute tensor dot product along specified axes for arrays >= 
> 1-D. 
> > >>     
> > >>     Given two tensors (arrays of dimension greater than or equal to 
> one), 
> > >>     ``a`` and ``b``, and an array_like object containing two 
> array_like 
> > >>     objects, ``(a_axes, b_axes)``, sum the products of ``a``'s and 
> > >>     ``b``'s 
> > >>     elements (components) over the axes specified by ``a_axes`` and 
> > >>     ``b_axes``. The third argument can be a single non-negative 
> > >>     integer_like scalar, ``N``; if it is such, then the last ``N`` 
> > >>     dimensions of ``a`` and the first ``N`` dimensions of ``b`` are 
> > >>     summed 
> > >>     over. 
> > >>     
> > >>     Parameters 
> > >>     ---------- 
> > >>     a, b : array_like, len(shape) >= 1 
> > >>     
> > >>         Tensors to "dot". 
> > >>     
> > >>     axes : variable type 
> > >>     
> > >>     * integer_like scalar 
> > >>     
> > >>       Number of axes to sum over (applies to both arrays); or 
> > >>     
> > >>     * array_like, shape = (2,), both elements array_like 
> > >>     
> > >>       Axes to be summed over, first sequence applying to ``a``, 
> second 
> > >>       to ``b``. 
> > >>     
> > >>     See Also 
> > >>     -------- 
> > >>     dot, einsum 
> > >>     
> > >>     Notes 
> > >>     ----- 
> > >>     When there is more than one axis to sum over - and they are not 
> the 
> > >>     last 
> > >>     (first) axes of ``a`` (``b``) - the argument ``axes`` should 
> consist 
> > >>     of 
> > >>     two sequences of the same length, with the first axis to sum over 
> > >>     given 
> > >>     first in both sequences, the second axis second, and so forth. 
> > >>     
> > >>     Examples 
> > >>     -------- 
> > >>     
> > >>     A "traditional" example: 
> > >>     >>> a = np.arange(60.).reshape(3,4,5) 
> > >>     >>> b = np.arange(24.).reshape(4,3,2) 
> > >>     >>> c = np.tensordot(a,b, axes=([1,0],[0,1])) 
> > >>     >>> c.shape 
> > >>     
> > >>     (5, 2) 
> > >>     
> > >>     >>> c 
> > >>     
> > >>     array([[ 4400.,  4730.], 
> > >>     
> > >>            [ 4532.,  4874.], 
> > >>            [ 4664.,  5018.], 
> > >>            [ 4796.,  5162.], 
> > >>            [ 4928.,  5306.]]) 
> > >>     >>> 
> > >>     >>> # A slower but equivalent way of computing the same... 
> > >>     >>> d = np.zeros((5,2)) 
> > >>     
> > >>     >>> for i in range(5): 
> > >>     ...   for j in range(2): 
> > >>     ...     for k in range(3): 
> > >>     ...       for n in range(4): 
> > >>     ...         d[i,j] += a[k,n,i] * b[n,k,j] 
> > >>     
> > >>     >>> c == d 
> > >>     
> > >>     array([[ True,  True], 
> > >>     
> > >>            [ True,  True], 
> > >>            [ True,  True], 
> > >>            [ True,  True], 
> > >>            [ True,  True]], dtype=bool) 
> > >>     
> > >>     """ 
> > >> 
> > >> I think the functionality laid out in the explicit for loops would be 
> > >> quite easy to replicate using the @nloops and @nref macros in 
> Cartesian, 
> > >> but I am not sure if that will be most performant way to implement 
> such a 
> > >> function. Also, I wanted to check here to see if this has already 
> been 
> > >> done 
> > >> before I spend some time working on this. 
> > >> 
> > >> Thanks, 
>
> ​

Reply via email to