comparison LazyTensors/src/LazyTensors.jl @ 190:8964b3165097 boundary_conditions

Break LazyTensors.jl into several files
author Jonatan Werpers <jonatan@werpers.com>
date Thu, 20 Jun 2019 22:48:07 +0200
parents 715ff09bb2ce
children 634453a4e1d8
comparison
equal deleted inserted replaced
189:e8e21db70112 190:8964b3165097
1 module LazyTensors 1 module LazyTensors
2 2
3 3 include("tensor_mapping.jl")
4 """ 4 include("lazy_operations.jl")
5 TensorMapping{T,R,D}
6
7 Describes a mapping of a D dimension tensor to an R dimension tensor.
8 The action of the mapping is implemented through the method
9
10 apply(t::TensorMapping{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {R,D,T}
11
12 The size of range tensor should be dependent on the size of the domain tensor
13 and the type should implement the methods
14
15 range_size(::TensorMapping{T,R,D}, domain_size::NTuple{D,Integer}) where {T,R,D}
16 domain_size(::TensorMapping{T,R,D}, range_size::NTuple{R,Integer}) where {T,R,D}
17
18 to allow querying for one or the other.
19
20 Optionally the action of the transpose may be defined through
21 apply_transpose(t::TensorMapping{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {R,D,T}
22 """
23 abstract type TensorMapping{T,R,D} end
24 export TensorMapping
25
26 """
27 apply(t::TensorMapping{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {R,D,T}
28
29 Return the result of the mapping for a given index.
30 """
31 function apply end
32 export apply
33
34 """
35 apply_transpose(t::TensorMapping{T,R,D}, v::AbstractArray{T,R}, I::Vararg) where {R,D,T}
36
37 Return the result of the transposed mapping for a given index.
38 """
39 function apply_transpose end
40 export apply_transpose
41
42 """
43 Return the dimension of the range space of a given mapping
44 """
45 range_dim(::TensorMapping{T,R,D}) where {T,R,D} = R
46
47 """
48 Return the dimension of the domain space of a given mapping
49 """
50 domain_dim(::TensorMapping{T,R,D}) where {T,R,D} = D
51
52 export range_dim, domain_dim
53
54 """
55 range_size(M::TensorMapping, domain_size)
56
57 Return the resulting range size for the mapping applied to a given domain_size
58 """
59 function range_size end
60
61 """
62 domain_size(M::TensorMapping, range_size)
63
64 Return the resulting domain size for the mapping applied to a given range_size
65 """
66 function domain_size end
67
68 export range_size, domain_size
69 # TODO: Think about boundschecking!
70
71
72 """
73 TensorOperator{T,D}
74
75 A `TensorMapping{T,D,D}` where the range and domain tensor have the same number of
76 dimensions and the same size.
77 """
78 abstract type TensorOperator{T,D} <: TensorMapping{T,D,D} end
79 export TensorOperator
80 domain_size(::TensorOperator{T,D}, range_size::NTuple{D,Integer}) where {T,D} = range_size
81 range_size(::TensorOperator{T,D}, domain_size::NTuple{D,Integer}) where {T,D} = domain_size
82
83
84
85 """
86 LazyTensorMappingTranspose{T,R,D} <: TensorMapping{T,D,R}
87
88 Struct for lazy transpose of a TensorMapping.
89
90 If a mapping implements the the `apply_transpose` method this allows working with
91 the transpose of mapping `m` by using `m'`. `m'` will work as a regular TensorMapping lazily calling
92 the appropriate methods of `m`.
93 """
94 struct LazyTensorMappingTranspose{T,R,D} <: TensorMapping{T,D,R}
95 tm::TensorMapping{T,R,D}
96 end
97 export LazyTensorMappingTranspose
98
99 # # TBD: Should this be implemented on a type by type basis or through a trait to provide earlier errors?
100 Base.adjoint(t::TensorMapping) = LazyTensorMappingTranspose(t)
101 Base.adjoint(t::LazyTensorMappingTranspose) = t.tm
102
103 apply(tm::LazyTensorMappingTranspose{T,R,D}, v::AbstractArray{T,R}, I::Vararg) where {T,R,D} = apply_transpose(tm.tm, v, I...)
104 apply_transpose(tm::LazyTensorMappingTranspose{T,R,D}, v::AbstractArray{T,D}, I::Vararg) where {T,R,D} = apply(tm.tm, v, I...)
105
106 range_size(tmt::LazyTensorMappingTranspose{T,R,D}, d_size::NTuple{R,Integer}) where {T,R,D} = domain_size(tmt.tm, domain_size)
107 domain_size(tmt::LazyTensorMappingTranspose{T,R,D}, r_size::NTuple{D,Integer}) where {T,R,D} = range_size(tmt.tm, range_size)
108
109
110 """
111 LazyTensorMappingApplication{T,R,D} <: AbstractArray{T,R}
112
113 Struct for lazy application of a TensorMapping. Created using `*`.
114
115 Allows the result of a `TensorMapping` applied to a vector to be treated as an `AbstractArray`.
116 With a mapping `m` and a vector `v` the LazyTensorMappingApplication object can be created by `m*v`.
117 The actual result will be calcualted when indexing into `m*v`.
118 """
119 struct LazyTensorMappingApplication{T,R,D} <: AbstractArray{T,R}
120 t::TensorMapping{T,R,D}
121 o::AbstractArray{T,D}
122 end
123 export LazyTensorMappingApplication
124
125 Base.:*(tm::TensorMapping{T,R,D}, o::AbstractArray{T,D}) where {T,R,D} = LazyTensorMappingApplication(tm,o)
126
127 Base.getindex(ta::LazyTensorMappingApplication{T,R,D}, I::Vararg) where {T,R,D} = apply(ta.t, ta.o, I...)
128 Base.size(ta::LazyTensorMappingApplication{T,R,D}) where {T,R,D} = range_size(ta.t,size(ta.o))
129 # TODO: What else is needed to implement the AbstractArray interface?
130
131
132 # # We need the associativity to be a→b→c = a→(b→c), which is the case for '→'
133 Base.:*(args::Union{TensorMapping{T}, AbstractArray{T}}...) where T = foldr(*,args)
134 # # Should we overload some other infix binary operator?
135 # →(tm::TensorMapping{T,R,D}, o::AbstractArray{T,D}) where {T,R,D} = LazyTensorMappingApplication(tm,o)
136 # TODO: We need to be really careful about good error messages.
137 # For example what happens if you try to multiply LazyTensorMappingApplication with a TensorMapping(wrong order)?
138
139
140
141 # struct LazyTensorMappingComposition{T,R,K,D} <: TensorMapping{T,R,D}
142 # t1::TensorMapping{T,R,K}
143 # t2::TensorMapping{T,K,D}
144 # end
145
146 # Base.:∘(s::TensorMapping{T,R,K}, t::TensorMapping{T,K,D}) where {T,R,K,D} = LazyTensorMappingComposition(s,t)
147
148 # function range_size(tm::LazyTensorMappingComposition{T,R,K,D}, domain_size::NTuple{D,Integer}) where {T,R,K,D}
149 # range_size(tm.t1, domain_size(tm.t2, domain_size))
150 # end
151
152 # function domain_size(tm::LazyTensorMappingComposition{T,R,K,D}, range_size::NTuple{R,Integer}) where {T,R,K,D}
153 # domain_size(tm.t1, domain_size(tm.t2, range_size))
154 # end
155
156 # function apply(c::LazyTensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::Vararg) where {T,R,K,D}
157 # apply(c.t1, LazyTensorMappingApplication(c.t2,v), I...)
158 # end
159
160 # function apply_transpose(c::LazyTensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::Vararg) where {T,R,K,D}
161 # apply_transpose(c.t2, LazyTensorMappingApplication(c.t1',v), I...)
162 # end
163
164 # # Have i gone too crazy with the type parameters? Maybe they aren't all needed?
165
166 # export →
167
168 5
169 end # module 6 end # module