comparison LazyTensors/src/lazy_operations.jl @ 194:d30d42a11566 boundary_conditions

Move all Lazy operation into the same module
author Jonatan Werpers <jonatan@werpers.com>
date Thu, 20 Jun 2019 23:11:30 +0200
parents 8964b3165097
children 5413067d2c4a
comparison
equal deleted inserted replaced
193:2d97c54fd1f1 194:d30d42a11566
53 # TODO: We need to be really careful about good error messages. 53 # TODO: We need to be really careful about good error messages.
54 # For example what happens if you try to multiply LazyTensorMappingApplication with a TensorMapping(wrong order)? 54 # For example what happens if you try to multiply LazyTensorMappingApplication with a TensorMapping(wrong order)?
55 55
56 56
57 57
58 """
59 LazyElementwiseOperation{T,D,Op, T1<:AbstractArray{T,D}, T2 <: AbstractArray{T,D}} <: AbstractArray{T,D}
60
61 Struct allowing for lazy evaluation of elementwise operations on AbstractArrays.
62
63 A LazyElementwiseOperation contains two AbstractArrays of equal size,
64 together with an operation. The operations are carried out when the
65 LazyElementwiseOperation is indexed.
66 """
67 struct LazyElementwiseOperation{T,D,Op, T1<:AbstractArray{T,D}, T2 <: AbstractArray{T,D}} <: AbstractArray{T,D}
68 a::T1
69 b::T2
70
71 function LazyElementwiseOperation{T,D,Op}(a::T1,b::T2) where {T,D,Op, T1<:AbstractArray{T,D}, T2<:AbstractArray{T,D}}
72 return new{T,D,Op,T1,T2}(a,b)
73 end
74 end
75
76 Base.size(v::LazyElementwiseOperation) = size(v.a)
77
78 # TODO: Make sure boundschecking is done properly and that the lenght of the vectors are equal
79 # NOTE: Boundschecking in getindex functions now assumes that the size of the
80 # vectors in the LazyElementwiseOperation are the same size. If we remove the
81 # size assertion in the constructor we might have to handle
82 # boundschecking differently.
83 Base.@propagate_inbounds @inline function Base.getindex(leo::LazyElementwiseOperation{T,D,:+}, I...) where {T,D}
84 @boundscheck if !checkbounds(Bool,leo.a,I...)
85 throw(BoundsError([leo],[I...]))
86 end
87 return leo.a[I...] + leo.b[I...]
88 end
89 Base.@propagate_inbounds @inline function Base.getindex(leo::LazyElementwiseOperation{T,D,:-}, I...) where {T,D}
90 @boundscheck if !checkbounds(Bool,leo.a,I...)
91 throw(BoundsError([leo],[I...]))
92 end
93 return leo.a[I...] - leo.b[I...]
94 end
95 Base.@propagate_inbounds @inline function Base.getindex(leo::LazyElementwiseOperation{T,D,:*}, I...) where {T,D}
96 @boundscheck if !checkbounds(Bool,leo.a,I...)
97 throw(BoundsError([leo],[I...]))
98 end
99 return leo.a[I...] * leo.b[I...]
100 end
101 Base.@propagate_inbounds @inline function Base.getindex(leo::LazyElementwiseOperation{T,D,:/}, I...) where {T,D}
102 @boundscheck if !checkbounds(Bool,leo.a,I...)
103 throw(BoundsError([leo],[I...]))
104 end
105 return leo.a[I...] / leo.b[I...]
106 end
107
108 # Define lazy operations for AbstractArrays. Operations constructs a LazyElementwiseOperation which
109 # can later be indexed into. Lazy operations are denoted by the usual operator followed by a tilde
110 @inline +̃(a::AbstractArray{T,D},b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:+}(a,b)
111 @inline -̃(a::AbstractArray{T,D},b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:-}(a,b)
112 @inline *̃(a::AbstractArray{T,D},b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:*}(a,b)
113 @inline /̃(a::AbstractArray{T,D},b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:/}(a,b)
114
115 # Abstract type for which the normal operations are defined by their
116 # lazy counterparts
117 abstract type LazyArray{T,D} <: AbstractArray{T,D} end;
118
119 Base.:+(a::LazyArray{T,D},b::AbstractArray{T,D}) where {T,D} = a +̃ b
120 Base.:+(a::AbstractArray{T,D}, b::LazyArray{T,D}) where {T,D} = b + a
121 Base.:-(a::LazyArray{T,D},b::AbstractArray{T,D}) where {T,D} = a -̃ b
122 Base.:-(a::AbstractArray{T,D}, b::LazyArray{T,D}) where {T,D} = a -̃ b
123 Base.:*(a::LazyArray{T,D},b::AbstractArray{T,D}) where {T,D} = a *̃ b
124 Base.:*(a::AbstractArray{T,D},b::LazyArray{T,D}) where {T,D} = b * a
125 # TODO: / seems to be ambiguous
126 # Base.:/(a::LazyArray{T,D},b::AbstractArray{T,D}) where {T,D} = a /̃ b
127 # Base.:/(a::AbstractArray{T,D},b::LazyArray{T,D}) where {T,D} = a /̃ b
128
129 export +̃, -̃, *̃, /̃, +, -, * #, /
130
131
132
133
134
58 # TODO: Write tests and documentation for LazyTensorMappingComposition 135 # TODO: Write tests and documentation for LazyTensorMappingComposition
59 # struct LazyTensorMappingComposition{T,R,K,D} <: TensorMapping{T,R,D} 136 # struct LazyTensorMappingComposition{T,R,K,D} <: TensorMapping{T,R,D}
60 # t1::TensorMapping{T,R,K} 137 # t1::TensorMapping{T,R,K}
61 # t2::TensorMapping{T,K,D} 138 # t2::TensorMapping{T,K,D}
62 # end 139 # end