# Tensor operations with AbstractArrays

**URL:** https://discourse.julialang.org/t/tensor-operations-with-abstractarrays/53504
**Category:** New to Julia
**Tags:** package
**Created:** [January 17, 2021, 10:28pm UTC](https://discourse.julialang.org/t/tensor-operations-with-abstractarrays/53504 "2021-01-17T22:28:47Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![schneiderfelipe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schneiderfelipe/32/18004_2.png) [@schneiderfelipe](https://discourse.julialang.org/u/schneiderfelipe)
#### Post date: [January 17, 2021, 10:28pm UTC](https://discourse.julialang.org/t/tensor-operations-with-abstractarrays/53504/1 "2021-01-17T22:28:47Z")

</div>

I’m looking after a way of doing the following operation. Here is an attempt using [TensorCast.jl](https://github.com/mcabbott/TensorCast.jl):

```julia
using TensorCast

# dummy data to simplify the example
n = 7
D = rand(n, n)
G = rand(7, 7, 7, 7)

@cast P[μ, ν] := D[λ, σ] * (G[μ, ν, σ, λ] - G[μ, λ, σ, ν] / 2)
# => ERROR: LoadError: can't find index λ on the left

```

I might be doing something wrong, but how could I make it work (possibly using another package)? I would like to have support of:

- arbitrary `AbstractArray`s (the `G` in my code is actually a custom type that wraps a matrix to deal with symmetries, so it is not contiguous in memory)
- matrices of type `LinearAlgebra.Hermitian` ([TensorOperations.jl appearently does not](https://github.com/Jutho/TensorOperations.jl/issues/102))

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [January 17, 2021, 10:33pm UTC](https://discourse.julialang.org/t/tensor-operations-with-abstractarrays/53504/2 "2021-01-17T22:33:30Z")

</div>

Does it work in Tullio.jl?

> **[GitHub - mcabbott/Tullio.jl: ⅀](https://github.com/mcabbott/Tullio.jl)**
>
> ⅀. Contribute to mcabbott/Tullio.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [January 17, 2021, 10:39pm UTC](https://discourse.julialang.org/t/tensor-operations-with-abstractarrays/53504/3 "2021-01-17T22:39:40Z")

</div>

I think what you want here is:

```julia
@reduce P[μ, ν] := sum(λ, σ) D[λ, σ] * (G[μ, ν, σ, λ] - G[μ, λ, σ, ν] / 2)

```

as `@cast` fairly literally only does broadcasting, it won’t ever call `sum` without being asked to. (Maybe the error message should say this, though!) Tullio (and Einsum and TensorOperations and OMEinsum) do automatically reduce over indices not shown on the left.

This ought to work with Hermitian, but it won’t exploit it to do things more efficiently.

---

<div class="post-metadata">

### Author: ![schneiderfelipe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schneiderfelipe/32/18004_2.png) [@schneiderfelipe](https://discourse.julialang.org/u/schneiderfelipe)
#### Post date: [January 18, 2021, 1:09am UTC](https://discourse.julialang.org/t/tensor-operations-with-abstractarrays/53504/4 "2021-01-18T01:09:51Z")

</div>

Awesome! It does work! Thanks for the solution and for suggesting Tullio.jl. It ended up being faster than TensorCast for what I want:

```julia
julia> @benchmark @tullio P[μ, ν] := D[λ, σ] * (G[μ, ν, σ, λ] - G[μ, λ, σ, ν] / 2)
BenchmarkTools.Trial: 
  memory estimate: 320 bytes
  allocs estimate: 2
  --------------
  minimum time: 49.161 μs (0.00% GC)
  median time: 49.634 μs (0.00% GC)
  mean time: 50.264 μs (0.00% GC)
  maximum time: 136.301 μs (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1

julia> @benchmark @cast P[μ, ν] := sum(λ, σ) D[λ, σ] * (G[μ, ν, σ, λ] - G[μ, λ, σ, ν] / 2)
BenchmarkTools.Trial: 
  memory estimate: 11.02 KiB
  allocs estimate: 28
  --------------
  minimum time: 62.962 μs (0.00% GC)
  median time: 63.602 μs (0.00% GC)
  mean time: 66.303 μs (0.62% GC)
  maximum time: 2.184 ms (95.12% GC)
  --------------
  samples: 10000
  evals/sample: 1

```
