Mercurial > repos > public > sbplib_julia
comparison src/LazyTensors/lazy_array.jl @ 333:01b851161018 refactor/combine_to_one_package
Start converting to one package by moving all the files to their correct location
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Fri, 25 Sep 2020 13:06:02 +0200 |
parents | LazyTensors/src/lazy_array.jl@41c3c25e4e3b |
children | 0a95a829176c 241bd2512c20 |
comparison
equal
deleted
inserted
replaced
332:535f1bff4bcc | 333:01b851161018 |
---|---|
1 """ | |
2 LazyArray{T,D} <: AbstractArray{T,D} | |
3 | |
4 Array which is calcualted lazily when indexing. | |
5 | |
6 A subtype of `LazyArray` will use lazy version of `+`, `-`, `*`, `/`. | |
7 """ | |
8 abstract type LazyArray{T,D} <: AbstractArray{T,D} end | |
9 export LazyArray | |
10 | |
11 struct LazyConstantArray{T,D} <: LazyArray{T,D} | |
12 val::T | |
13 size::NTuple{D,Int} | |
14 end | |
15 | |
16 Base.size(lca::LazyConstantArray) = lca.size | |
17 Base.getindex(lca::LazyConstantArray{T,D}, I::Vararg{Int,D}) where {T,D} = lca.val | |
18 | |
19 """ | |
20 LazyElementwiseOperation{T,D,Op} <: LazyArray{T,D} | |
21 Struct allowing for lazy evaluation of elementwise operations on AbstractArrays. | |
22 | |
23 A LazyElementwiseOperation contains two arrays together with an operation. | |
24 The operations are carried out when the LazyElementwiseOperation is indexed. | |
25 """ | |
26 struct LazyElementwiseOperation{T,D,Op} <: LazyArray{T,D} | |
27 a::AbstractArray{T,D} | |
28 b::AbstractArray{T,D} | |
29 | |
30 function LazyElementwiseOperation{T,D,Op}(a::AbstractArray{T,D},b::AbstractArray{T,D}) where {T,D,Op} | |
31 @boundscheck if size(a) != size(b) | |
32 throw(DimensionMismatch("dimensions must match")) | |
33 end | |
34 return new{T,D,Op}(a,b) | |
35 end | |
36 | |
37 LazyElementwiseOperation{T,D,Op}(a::AbstractArray{T,D},b::T) where {T,D,Op} = new{T,D,Op}(a, LazyConstantArray(b, size(a))) | |
38 LazyElementwiseOperation{T,D,Op}(a::T,b::AbstractArray{T,D}) where {T,D,Op} = new{T,D,Op}(LazyConstantArray(a, size(b)), b) | |
39 end | |
40 # TODO: Move Op to be the first parameter? Compare to Binary operations | |
41 | |
42 Base.size(v::LazyElementwiseOperation) = size(v.a) | |
43 | |
44 evaluate(leo::LazyElementwiseOperation{T,D,:+}, I::Vararg{Int,D}) where {T,D} = leo.a[I...] + leo.b[I...] | |
45 evaluate(leo::LazyElementwiseOperation{T,D,:-}, I::Vararg{Int,D}) where {T,D} = leo.a[I...] - leo.b[I...] | |
46 evaluate(leo::LazyElementwiseOperation{T,D,:*}, I::Vararg{Int,D}) where {T,D} = leo.a[I...] * leo.b[I...] | |
47 evaluate(leo::LazyElementwiseOperation{T,D,:/}, I::Vararg{Int,D}) where {T,D} = leo.a[I...] / leo.b[I...] | |
48 | |
49 # TODO: Make sure boundschecking is done properly and that the lenght of the vectors are equal | |
50 # NOTE: Boundschecking in getindex functions now assumes that the size of the | |
51 # vectors in the LazyElementwiseOperation are the same size. If we remove the | |
52 # size assertion in the constructor we might have to handle | |
53 # boundschecking differently. | |
54 Base.@propagate_inbounds @inline function Base.getindex(leo::LazyElementwiseOperation{T,D}, I::Vararg{Int,D}) where {T,D} | |
55 @boundscheck if !checkbounds(Bool, leo.a, I...) | |
56 throw(BoundsError([leo], I...)) | |
57 end | |
58 return evaluate(leo, I...) | |
59 end | |
60 | |
61 # Define lazy operations for AbstractArrays. Operations constructs a LazyElementwiseOperation which | |
62 # can later be indexed into. Lazy operations are denoted by the usual operator followed by a tilde | |
63 Base.@propagate_inbounds +̃(a::AbstractArray{T,D}, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:+}(a,b) | |
64 Base.@propagate_inbounds -̃(a::AbstractArray{T,D}, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:-}(a,b) | |
65 Base.@propagate_inbounds *̃(a::AbstractArray{T,D}, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:*}(a,b) | |
66 Base.@propagate_inbounds /̃(a::AbstractArray{T,D}, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:/}(a,b) | |
67 | |
68 Base.@propagate_inbounds +̃(a::AbstractArray{T,D}, b::T) where {T,D} = LazyElementwiseOperation{T,D,:+}(a,b) | |
69 Base.@propagate_inbounds -̃(a::AbstractArray{T,D}, b::T) where {T,D} = LazyElementwiseOperation{T,D,:-}(a,b) | |
70 Base.@propagate_inbounds *̃(a::AbstractArray{T,D}, b::T) where {T,D} = LazyElementwiseOperation{T,D,:*}(a,b) | |
71 Base.@propagate_inbounds /̃(a::AbstractArray{T,D}, b::T) where {T,D} = LazyElementwiseOperation{T,D,:/}(a,b) | |
72 | |
73 Base.@propagate_inbounds +̃(a::T, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:+}(a,b) | |
74 Base.@propagate_inbounds -̃(a::T, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:-}(a,b) | |
75 Base.@propagate_inbounds *̃(a::T, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:*}(a,b) | |
76 Base.@propagate_inbounds /̃(a::T, b::AbstractArray{T,D}) where {T,D} = LazyElementwiseOperation{T,D,:/}(a,b) | |
77 | |
78 | |
79 | |
80 # NOTE: Är det knas att vi har till exempel * istället för .* ?? | |
81 # Oklart om det ens går att lösa.. | |
82 Base.@propagate_inbounds Base.:+(a::LazyArray{T,D}, b::LazyArray{T,D}) where {T,D} = a +̃ b | |
83 Base.@propagate_inbounds Base.:+(a::LazyArray{T,D}, b::AbstractArray{T,D}) where {T,D} = a +̃ b | |
84 Base.@propagate_inbounds Base.:+(a::AbstractArray{T,D}, b::LazyArray{T,D}) where {T,D} = a +̃ b | |
85 | |
86 Base.@propagate_inbounds Base.:-(a::LazyArray{T,D}, b::LazyArray{T,D}) where {T,D} = a -̃ b | |
87 Base.@propagate_inbounds Base.:-(a::LazyArray{T,D}, b::AbstractArray{T,D}) where {T,D} = a -̃ b | |
88 Base.@propagate_inbounds Base.:-(a::AbstractArray{T,D}, b::LazyArray{T,D}) where {T,D} = a -̃ b | |
89 | |
90 # Element wise operation for `*` and `\` are not overloaded due to conflicts with the behavior | |
91 # of regular `*` and `/` for AbstractArrays. Use tilde versions instead. | |
92 | |
93 export +̃, -̃, *̃, /̃ |