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