Mercurial > repos > public > sbplib_julia
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 |