comparison LazyTensors/src/LazyTensors.jl @ 186:715ff09bb2ce boundary_conditions

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