Mercurial > repos > public > sbplib_julia
comparison TensorMappings.jl @ 155:9fdbae11dd77 boundary_conditions
Add sketch of how Implicitly definied tensor mappings might work
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Tue, 23 Apr 2019 09:54:42 +0200 |
parents | |
children | ef3e6c70b6f9 |
comparison
equal
deleted
inserted
replaced
154:3193bac1c086 | 155:9fdbae11dd77 |
---|---|
1 module TensorMappings | |
2 # Needs a better name ImplicitTensorMappings? Get rid of "Tensor" in the name_ | |
3 | |
4 abstract type TensorMapping{T,R,D} end | |
5 abstract type TensorOperator{T,D} <: TensorMapping{T,D,D} end # Does this help? | |
6 | |
7 range_dim(::TensorMapping{T,R,D}) where {T,R,D} = R | |
8 domain_dim(::TensorMapping{T,R,D}) where {T,R,D} = D | |
9 | |
10 range_size(::TensorOperator{T,D}, domain_size::NTuple{D,Integer}) where {T,D} = domain_size | |
11 # More prciese domain_size type? | |
12 | |
13 # Should be implemented by a TensorMapping | |
14 # ======================================== | |
15 # apply(t::TensorMapping{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {R,D,T} = | |
16 # apply_transpose(t::TensorMapping{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {R,D,T} = | |
17 # Does it make sense that apply should work for any size of v? And the application adapts? | |
18 # Think about boundschecking! | |
19 | |
20 # range_size(::TensorMapping{T,R,D}, domain_size::NTuple{D,Integer}) where {T,R,D} = | |
21 # More prciese domain_size type? | |
22 # range_size_of_transpose()??? | |
23 | |
24 | |
25 | |
26 # Allow using the ' operator: | |
27 struct TensorMappingTranspose{T,R,D} <: TensorMapping{T,D,R} | |
28 tm::TensorMapping{T,R,D} | |
29 end | |
30 | |
31 Base.adjoint(t::TensorMapping) = TensorMappingTranspose(t) # Maybe this should be implemented on a type by type basis or through a trait to provide earlier errors. | |
32 Base.adjoint(t::TensorMappingTranspose) = t.tm | |
33 | |
34 apply(tm::TensorMappingTranspose{T,R,D}, v::AbstractArray{T,R}, I::Vararg) where {T,R,D} = apply_transpose(tm.tm, v, I...) | |
35 apply_transpose(tm::TensorMappingTranspose{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {T,R,D} = apply(tm.tm, v, I...) | |
36 | |
37 # range_size(::TensorMappingTranspose{T,R,D}, domain_size::NTuple{}) = range_size_of_transpose??? | |
38 | |
39 struct TensorApplication{T,R,D} <: AbstractArray{T,R} | |
40 t::TensorMapping{R,D} | |
41 o::AbstractArray{T,D} | |
42 end | |
43 | |
44 Base.size(ta::TensorApplication) = range_size(ta.t,size(ta.o)) | |
45 ## What else is needed so that we have a proper AbstractArray? | |
46 | |
47 Base.getindex(tm::TensorApplication, I::Vararg) = apply(tm.t, tm.o, I...) | |
48 | |
49 →(t::TensorMapping{R,D}, o::AbstractArray{T,D}) where {T,R,D} = TensorApplication(t,o) | |
50 # Should we overload some other infix binary operator? | |
51 # * has the wrong parsing properties... a*b*c is parsed to (a*b)*c (through a*b*c = *(a,b,c)) | |
52 # while a→b→c is parsed as a→(b→c) | |
53 # The associativity of the operators might be fixed somehow... (rfold/lfold?) | |
54 # ∘ also is an option but that has the same problem as * (but is not n-ary) (or is this best used for composition of Mappings?) | |
55 | |
56 | |
57 struct TensorMappingComposition{T,R,K,D} <: TensorMapping{T,R,D} | |
58 t1::TensorMapping{T,R,K} | |
59 t2::TensorMapping{T,K,D} | |
60 end | |
61 | |
62 import Base.∘ | |
63 ∘(s::TensorMapping{T,R,K}, t::TensorMapping{T,K,D}) where {T,R,K,D} = TensorMappingComposition(s,t) | |
64 | |
65 function apply(c::TensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::Vararg) where {T,R,K,D} | |
66 apply(c.t1, TensorApplication(c.t2,v), I...) | |
67 end | |
68 | |
69 function apply_transpose(c::TensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::Vararg) where {T,R,K,D} | |
70 apply_transpose(c.t2, TensorApplication(c.t1',v), I...) | |
71 end | |
72 | |
73 # Have i gone too crazy with the type parameters? Maybe they aren't all needed? | |
74 | |
75 | |
76 export apply | |
77 export apply_transpose | |
78 export range_dim | |
79 export domain_dim | |
80 export range_size | |
81 export → | |
82 | |
83 | |
84 end #module |