comparison src/LazyTensors/lazy_tensor_operations.jl @ 447:27e0e256e5d9 feature/inflated_tensormapping

Merge in feature/lazy_identity
author Jonatan Werpers <jonatan@werpers.com>
date Mon, 19 Oct 2020 20:59:08 +0200
parents 904aae1899df 648a36ebac99
children 912ae510dec9
comparison
equal deleted inserted replaced
446:904aae1899df 447:27e0e256e5d9
72 domain_size(tmBinOp::LazyTensorMappingBinaryOperation{Op,T,R,D}) where {Op,T,R,D} = domain_size(tmBinOp.tm1) 72 domain_size(tmBinOp::LazyTensorMappingBinaryOperation{Op,T,R,D}) where {Op,T,R,D} = domain_size(tmBinOp.tm1)
73 73
74 Base.:+(tm1::TensorMapping{T,R,D}, tm2::TensorMapping{T,R,D}) where {T,R,D} = LazyTensorMappingBinaryOperation{:+,T,R,D}(tm1,tm2) 74 Base.:+(tm1::TensorMapping{T,R,D}, tm2::TensorMapping{T,R,D}) where {T,R,D} = LazyTensorMappingBinaryOperation{:+,T,R,D}(tm1,tm2)
75 Base.:-(tm1::TensorMapping{T,R,D}, tm2::TensorMapping{T,R,D}) where {T,R,D} = LazyTensorMappingBinaryOperation{:-,T,R,D}(tm1,tm2) 75 Base.:-(tm1::TensorMapping{T,R,D}, tm2::TensorMapping{T,R,D}) where {T,R,D} = LazyTensorMappingBinaryOperation{:-,T,R,D}(tm1,tm2)
76 76
77 77 """
78 # TODO: Write tests and documentation for LazyTensorMappingComposition 78 TensorMappingComposition{T,R,K,D}
79 # struct LazyTensorMappingComposition{T,R,K,D} <: TensorMapping{T,R,D} 79
80 # t1::TensorMapping{T,R,K} 80 Lazily compose two TensorMappings, so that they can be handled as a single TensorMapping.
81 # t2::TensorMapping{T,K,D} 81 """
82 # end 82 struct TensorMappingComposition{T,R,K,D, TM1<:TensorMapping{T,R,K}, TM2<:TensorMapping{T,K,D}} <: TensorMapping{T,R,D}
83 83 t1::TM1
84 # Base.:∘(s::TensorMapping{T,R,K}, t::TensorMapping{T,K,D}) where {T,R,K,D} = LazyTensorMappingComposition(s,t) 84 t2::TM2
85 85
86 # function range_size(tm::LazyTensorMappingComposition{T,R,K,D}, domain_size::NTuple{D,Integer}) where {T,R,K,D} 86 @inline function TensorMappingComposition(t1::TensorMapping{T,R,K}, t2::TensorMapping{T,K,D}) where {T,R,K,D}
87 # range_size(tm.t1, domain_size(tm.t2, domain_size)) 87 @boundscheck if domain_size(t1) != range_size(t2)
88 # end 88 throw(DimensionMismatch("the first argument has domain size $(domain_size(t1)) while the second has range size $(range_size(t2)) "))
89 89 end
90 # function domain_size(tm::LazyTensorMappingComposition{T,R,K,D}, range_size::NTuple{R,Integer}) where {T,R,K,D} 90 return new{T,R,K,D, typeof(t1), typeof(t2)}(t1,t2)
91 # domain_size(tm.t1, domain_size(tm.t2, range_size)) 91 end
92 # end 92 # Add check for matching sizes as a boundscheck
93 93 end
94 # function apply(c::LazyTensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::NTuple{R,Int}) where {T,R,K,D} 94 export TensorMappingComposition
95 # apply(c.t1, LazyTensorMappingApplication(c.t2,v), I...) 95
96 # end 96 range_size(tm::TensorMappingComposition) = range_size(tm.t1)
97 97 domain_size(tm::TensorMappingComposition) = domain_size(tm.t2)
98 # function apply_transpose(c::LazyTensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::NTuple{D,Int}) where {T,R,K,D} 98
99 # apply_transpose(c.t2, LazyTensorMappingApplication(c.t1',v), I...) 99 function apply(c::TensorMappingComposition{T,R,K,D}, v::AbstractArray{T,D}, I::Vararg{S,R} where S) where {T,R,K,D}
100 # end 100 apply(c.t1, c.t2*v, I...)
101 101 end
102 # # Have i gone too crazy with the type parameters? Maybe they aren't all needed? 102
103 103 function apply_transpose(c::TensorMappingComposition{T,R,K,D}, v::AbstractArray{T,R}, I::Vararg{S,D} where S) where {T,R,K,D}
104 # export → 104 apply_transpose(c.t2, c.t1'*v, I...)
105 end
106
107 Base.@propagate_inbounds Base.:∘(s::TensorMapping, t::TensorMapping) = TensorMappingComposition(s,t)
108
105 """ 109 """
106 LazyLinearMap{T,R,D,...}(A, range_indicies, domain_indicies) 110 LazyLinearMap{T,R,D,...}(A, range_indicies, domain_indicies)
107 111
108 TensorMapping defined by the AbstractArray A. `range_indicies` and `domain_indicies` define which indicies of A should 112 TensorMapping defined by the AbstractArray A. `range_indicies` and `domain_indicies` define which indicies of A should
109 be considerd the range and domain of the TensorMapping. Each set of indices must be ordered in ascending order. 113 be considerd the range and domain of the TensorMapping. Each set of indices must be ordered in ascending order.
142 apply(LazyLinearMap(llm.A, llm.domain_indicies, llm.range_indicies), v, I...) 146 apply(LazyLinearMap(llm.A, llm.domain_indicies, llm.range_indicies), v, I...)
143 end 147 end
144 148
145 149
146 """ 150 """
147 LazyIdentity{T,D} <: TensorMapping{T,D,D} 151 IdentityMapping{T,D} <: TensorMapping{T,D,D}
148 152
149 The lazy identity TensorMapping for a given size. Usefull for building up higher dimensional tensor mappings from lower 153 The lazy identity TensorMapping for a given size. Usefull for building up higher dimensional tensor mappings from lower
150 dimensional ones through outer products. Also used in the Implementation for InflatedTensorMapping. 154 dimensional ones through outer products. Also used in the Implementation for InflatedTensorMapping.
151 """ 155 """
152 struct LazyIdentity{T,D} <: TensorMapping{T,D,D} 156 struct IdentityMapping{T,D} <: TensorMapping{T,D,D}
153 size::NTuple{D,Int} 157 size::NTuple{D,Int}
154 end 158 end
155 export LazyIdentity 159 export IdentityMapping
156 160
157 LazyIdentity{T}(size::NTuple{D,Int}) where {T,D} = LazyIdentity{T,D}(size) 161 IdentityMapping{T}(size::NTuple{D,Int}) where {T,D} = IdentityMapping{T,D}(size)
158 162
159 range_size(tmi::LazyIdentity) = tmi.size 163 range_size(tmi::IdentityMapping) = tmi.size
160 domain_size(tmi::LazyIdentity) = tmi.size 164 domain_size(tmi::IdentityMapping) = tmi.size
161 165
162 apply(tmi::LazyIdentity{T,D}, v::AbstractArray{T,D}, I::Vararg{Index,D}) where {T,D} = v[Int.(I)...] 166 apply(tmi::IdentityMapping{T,D}, v::AbstractArray{T,D}, I::Vararg{Any,D}) where {T,D} = v[I...]
163 apply_transpose(tmi::LazyIdentity{T,D}, v::AbstractArray{T,D}, I::Vararg{Index,D}) where {T,D} = v[Int.(I)...] 167 apply_transpose(tmi::IdentityMapping{T,D}, v::AbstractArray{T,D}, I::Vararg{Any,D}) where {T,D} = v[I...]
164 168
165 struct InflatedTensorMapping{T,R,D,D_before,R_middle,D_middle,D_after} <: TensorMapping{T,R,D} 169 struct InflatedTensorMapping{T,R,D,D_before,R_middle,D_middle,D_after} <: TensorMapping{T,R,D}
166 before::LazyIdentity{T,D_before} 170 before::LazyIdentity{T,D_before}
167 tm::TensorMapping{T,R_middle,D_middle} 171 tm::TensorMapping{T,R_middle,D_middle}
168 after::LazyIdentity{T,D_after} 172 after::LazyIdentity{T,D_after}