- Notifications
You must be signed in to change notification settings - Fork5
Tensor algebra abstract type interoperability setup
License
chakravala/AbstractTensors.jl
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Tensor algebra abstract type interoperability with vector bundle parameter
TheAbstractTensors package is intended for universal interoperability of the abstractTensorAlgebra type system.AllTensorAlgebra{V} subtypes have type parameterV, used to store aTensorBundle value obtained fromDirectSum.jl.
For example, this is mainly used inGrassmann.jl to define variousSubAlgebra,TensorGraded andTensorMixed types, each with subtypes. Externalizing the abstract type helps extend the dispatch to other packages.By itself, this package does not impose any specifications or structure on theTensorAlgebra{V} subtypes and elements, aside from requiringV to be aManifold.This means that different packages can create tensor types having a common underlyingTensorBundle structure.
Additionally,TupleVector is provided as a light weight alternative toStaticArrays.jl.
If the environment variableSTATICJL is set, theStaticArrays package is depended upon.
SinceTensorBundle choices are fundamental toTensorAlgebra operations, the universal interoperability betweenTensorAlgebra{V} elements with different associatedTensorBundle choices is naturally realized by applying theunion morphism to operations.
functionop(::TensorAlgebra{V},::TensorAlgebra{V})where V# well defined operations if V is sharedend# but what if V ≠ W in the input types?functionop(a::TensorAlgebra{V},b::TensorAlgebra{W})where {V,W} VW= V∪ W# VectorSpace type unionop(VW(a),VW(b))# makes call well-definedend# this option is automatic with interop(a,b)# alternatively for evaluation of forms, VW(a)(VW(b))
Some of operations like+,-,*,⊗,⊛,⊙,⊠,⨼,⨽,⋆ and postfix operators⁻¹,ǂ,₊,₋,ˣ forTensorAlgebra elements are shared across different packages, some of the interoperability is taken care of in this package.Additionally, a universal unit volume element can be specified in terms ofLinearAlgebra.UniformScaling, which is independent ofV and has its interpretation only instantiated by the context of theTensorAlgebra{V} element being operated on.
Utility methods such asscalar, involute, norm, norm2, unit, even, odd are also defined.
Suppose we are dealing with a new subtype in another project, such as
using AbstractTensors, DirectSumstruct SpecialTensor{V}<:TensorAlgebra{V}enda=SpecialTensor{ℝ}()b=SpecialTensor{ℝ'}()
To define additional specialized interoperability for further methods, it is necessary to define dispatch that catches well-defined operations for equalTensorBundle choices and a fallback method for interoperability, along with aManifold morphism:
(W::Signature)(s::SpecialTensor{V})where V=SpecialTensor{W}()# conversionsop(a::SpecialTensor{V},b::SpecialTensor{V})where V= a# do some kind of operationop(a::TensorAlgebra{V},b::TensorAlgebra{W})where {V,W}=interop(op,a,b)# compat
which should satisfy (using the∪ operation as defined inDirectSum)
julia>op(a,b)|> Manifold==Manifold(a)∪Manifold(b)true
Thus, interoperability is simply a matter of defining one additional fallback method for the operation and also a new formTensorBundle compatibility morphism.
The universal interoperability ofLinearAlgebra.UniformScaling as a pseudoscalar element which takes on theTensorBundle form of any otherTensorAlgebra element is handled globally by defining the dispatch:
(W::Signature)(s::UniformScaling)=ones(ndims(W))# interpret a unit pseudoscalarop(a::TensorAlgebra{V},b::UniformScaling)where V=op(a,V(b))# right pseudoscalarop(a::UniformScaling,b::TensorAlgebra{V})where V=op(V(a),b)# left pseudoscalar
This enables the usage ofI fromLinearAlgebra as a universal pseudoscalar element.
To support a generalized interface forTensorAlgebra element evaluation, a similar compatibility interface is constructible.
(a::SpecialTensor{V})(b::SpecialTensor{V})where V= a# conversion of some form(a::SpecialTensor{W})(b::SpecialTensor{V})where {V,W}=interform(a,b)# compat
which should satisfy (using the∪ operation as defined inDirectSum)
julia>b(a)|> Manifold==Manifold(a)∪Manifold(b)true
The purpose of theinterop andinterform methods is to help unify the interoperability ofTensorAlgebra elements.
The key to making the whole interoperability work is that eachTensorAlgebra subtype shares aTensorBundle parameter (with allisbitstype parameters), which contains all the info needed at compile time to make decisions about conversions. So other packages need only use the vector space information to decide on how to convert based on the implementation of a type. If external methods are needed, they can be loaded byRequires when making a separate package withTensorAlgebra interoperability.
Statically sized tuple vectors for Julia
TupleVector provides a framework for implementing statically sized tuple vectorsin Julia, using the abstract typeTupleVector{N,T} <: AbstractVector{T}.Subtypes ofTupleVector will provide fast implementations of common array andlinear algebra operations. Note that here "statically sized" means that thesize can be determined from thetype, and "static" doesnot necessarilyimplyimmutable.
The package also provides some concrete static vector types:Values which may be used as-is (or else embedded in your own type).Mutable versionsVariables are also exported, as wellasFixedVector for annotating standardVectors with static size information.
AddAbstractTensors from thePkg REPL, i.e.,pkg> add AbstractTensors. Then:
using AbstractTensors# Create Values using various forms, using constructors, functions or macrosv1=Values(1,2,3)v1.v=== (1,2,3)# Values uses a tuple for internal storagev2=Values{3,Float64}(1,2,3)# length 3, eltype Float64v5=zeros(Values{3})# defaults to Float64v7=Values{3}([1,2,3])# Array conversions must specify size# Can get size() from instance or typesize(v1)== (3,)size(typeof(v1))== (3,)# Supports all the common operations of AbstractVectorv7= v1+ v2v8=sin.(v2)# Indexing can also be done using static vectors of integersv1[1]===1v1[:]=== v1typeof(v1[[1,2,3]])<:Vector# Can't determine size from the type of [1,2,3]
The package provides a range of different useful built-inTupleVector types,which include mutable and immutable vectors based upon tuples, vectors based uponstructs, and wrappers ofVector. There is a relatively simple interface forcreating your own, customTupleVector types, too.
This package also provides methods for a wide range ofAbstractVector functions,specialized for (potentially immutable)TupleVectors. Many of Julia'sbuilt-in method definitions inherently assume mutability, and furtherperformance optimizations may be made when the size of the vector is known to thecompiler. One example of this is by loop unrolling, which has a substantialeffect on small arrays and tends to automatically trigger LLVM's SIMDoptimizations. In combination with intelligent fallbacks tothe methods in Base, we seek to provide a comprehensive support for staticallysized vectors, large or small, that hopefully "just works".
TupleVector is directly inspired fromStaticArrays.jl.
About
Tensor algebra abstract type interoperability setup
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Contributors2
Uh oh!
There was an error while loading.Please reload this page.