Skip to content

Manipulate tensors symbolically in Julia! Currently needs a SymPy dependency, but work is ongoing to change the backend to SymbolicUtils.jl

License

Notifications You must be signed in to change notification settings

rjrosati/SymbolicTensors.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SymbolicTensors

Build Status codecov

Many numerical tensor manipulation packages exist (e.g. Einsum.jl), but treating tensors at a purely numeric level throws away a lot of potential optimizations. Often, it's possible to exploit the symmetries of a problem to dramatically reduce the calculation steps necessary, or perform some tensor contractions symbolically rather than numerically.

SymbolicTensors.jl is designed to exploit these simplifications to perform symbolic calculations and generate more efficient input into numeric tensor packages than you would write by hand. It based on SymPy.jl, sympy.tensor.tensor, xTensor, and ITensors.jl.

See the talk about this package given at JuliaCon 2020: https://www.youtube.com/watch?v=_b4JIv044GY

Example calculations

using SymbolicTensors
using SymPy

spacetime = TensorIndexType("spacetime","f")
@indices spacetime μ ν σ ρ η
x = TensorHead("x",[spacetime])
δ = spacetime.delta
# one way to write the metric on a sphere
g = 4*δ(-μ,-ν)/(1+x(μ)*x(ν)*δ(-μ,-ν))^2

# compute the christoffel symbols
Γ = (diff(g(-μ,-ν),x(σ)) - diff(g(-ν,-σ),x(μ)) + diff(g(-σ,-μ),x(ν)))/2
Γ = factor(contract_metric(canon_bp(Γ),spacetime.metric))

At this point Γ is a symbolic tensor expression, written in Einstein notation. It could represent 2 dimensional or 10,000 dimensional tensors in the same form -- this is one of the great advantages of working at the symbolic tensor level.

We could manipulate Γ further, or convert it into an array.

# convert Γ to Array{Sym}
xarr = symbols("x y",real=true)
garr = replace_with_arrays(g,Dict(x(ρ) => xarr, spacetime.delta(-ρ,-η) => [1 0; 0 1]))
Γarr = replace_with_arrays(Γ,Dict(x(ρ) => xarr, spacetime.delta(-ρ,-η) => [1 0; 0 1], spacetime => garr))

Now that we have an array in Γarr, Quote allows us to convert it into a native Julia function.

# Then Quote it and eval to a Julia function
quot = Quote("Christoffel",Γarr,[ x for x in xarr])
Christ = eval(quot)
Christ(0,1)

Rough TODO

  • Nicer errors
  • testing coverage
  • add conversion to ITensors or equivalent
  • documentation
  • symbolic derivatives?

known bugs

  • check issues

About

Manipulate tensors symbolically in Julia! Currently needs a SymPy dependency, but work is ongoing to change the backend to SymbolicUtils.jl

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages