1
1
module ContinuumArrays
2
2
using IntervalSets, LinearAlgebra, LazyArrays, FillArrays, BandedMatrices, QuasiArrays
3
- import Base: @_inline_meta , axes, getindex, convert, prod, * , / , \ , + , - ,
3
+ import Base: @_inline_meta , @_propagate_inbounds_meta , axes, getindex, convert, prod, * , / , \ , + , - , == ,
4
4
IndexStyle, IndexLinear, == , OneTo, tail, similar, copyto!, copy,
5
- first, last, show
6
- import Base. Broadcast: materialize, BroadcastStyle
7
- import LazyArrays: MemoryLayout, Applied, ApplyStyle, flatten, _flatten, colsupport, adjointlayout, LdivApplyStyle
5
+ first, last, show, isempty, findfirst, findlast, findall, Slice
6
+ import Base. Broadcast: materialize, BroadcastStyle, broadcasted
7
+ import LazyArrays: MemoryLayout, Applied, ApplyStyle, flatten, _flatten, colsupport,
8
+ adjointlayout, LdivApplyStyle, arguments, broadcastlayout, lazy_getindex,
9
+ sublayout, ApplyLayout, BroadcastLayout, combine_mul_styles
8
10
import LinearAlgebra: pinv
9
11
import BandedMatrices: AbstractBandedLayout, _BandedMatrix
10
12
import FillArrays: AbstractFill, getindex_value
11
13
12
14
import QuasiArrays: cardinality, checkindex, QuasiAdjoint, QuasiTranspose, Inclusion, SubQuasiArray,
13
- QuasiDiagonal, MulQuasiArray, MulQuasiMatrix, MulQuasiVector, QuasiMatMulMat,
15
+ QuasiDiagonal, MulQuasiArray, MulQuasiMatrix, MulQuasiVector, QuasiMatMulMat, quasimulapplystyle,
14
16
ApplyQuasiArray, ApplyQuasiMatrix, LazyQuasiArrayApplyStyle, AbstractQuasiArrayApplyStyle,
15
17
LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle
16
18
17
- export Spline, LinearSpline, HeavisideSpline, DiracDelta, Derivative, fullmaterialize, ℵ₁, Inclusion, Basis, WeightedBasis
19
+ export Spline, LinearSpline, HeavisideSpline, DiracDelta, Derivative, fullmaterialize, ℵ₁, Inclusion, Basis, WeightedBasis, grid
18
20
19
21
# ###
20
22
# Interval indexing support
@@ -38,35 +40,85 @@ const QMul3{A,B,C} = Mul{<:AbstractQuasiArrayApplyStyle, <:Tuple{A,B,C}}
38
40
cardinality (:: AbstractInterval ) = ℵ₁
39
41
* (ℵ:: AlephInfinity ) = ℵ
40
42
43
+ Inclusion (d:: AbstractInterval{T} ) where T = Inclusion {float(T)} (d)
41
44
first (S:: Inclusion{<:Any,<:AbstractInterval} ) = leftendpoint (S. domain)
42
45
last (S:: Inclusion{<:Any,<:AbstractInterval} ) = rightendpoint (S. domain)
43
46
47
+ for find in (:findfirst , :findlast )
48
+ @eval $ find (f:: Base.Fix2{typeof(isequal)} , d:: Inclusion ) = f. x in d. domain ? f. x : nothing
49
+ end
44
50
45
- checkindex (:: Type{Bool} , inds:: AbstractInterval , i:: Number ) = (leftendpoint (inds) <= i) & (i <= rightendpoint (inds))
46
- checkindex (:: Type{Bool} , inds:: AbstractInterval , i:: Inclusion ) = i. domain ⊆ inds
47
- function checkindex (:: Type{Bool} , inds:: AbstractInterval , I:: AbstractArray )
48
- @_inline_meta
49
- b = true
50
- for i in I
51
- b &= checkindex (Bool, inds, i)
52
- end
53
- b
51
+ function findall (f:: Base.Fix2{typeof(isequal)} , d:: Inclusion )
52
+ r = findfirst (f,d)
53
+ r === nothing ? eltype (d)[] : [r]
54
54
end
55
55
56
56
57
- # we represent as a Mul with a banded matrix
58
- function materialize (V:: SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:Inclusion,<:AbstractUnitRange}} )
59
- A = parent (V)
60
- _,jr = parentindices (V)
61
- first (jr) ≥ 1 || throw (BoundsError ())
62
- P = _BandedMatrix (Ones {Int} (1 ,length (jr)), axes (A,2 ), first (jr)- 1 ,1 - first (jr))
63
- A* P
57
+ function checkindex (:: Type{Bool} , inds:: Inclusion{<:Any,<:AbstractInterval} , r:: Inclusion{<:Any,<:AbstractInterval} )
58
+ @_propagate_inbounds_meta
59
+ isempty (r) | (checkindex (Bool, inds, first (r)) & checkindex (Bool, inds, last (r)))
64
60
end
65
61
62
+
66
63
BroadcastStyle (:: Type{<:Inclusion{<:Any,<:AbstractInterval}} ) = LazyQuasiArrayStyle {1} ()
67
64
BroadcastStyle (:: Type{<:QuasiAdjoint{<:Any,<:Inclusion{<:Any,<:AbstractInterval}}} ) = LazyQuasiArrayStyle {2} ()
68
65
BroadcastStyle (:: Type{<:QuasiTranspose{<:Any,<:Inclusion{<:Any,<:AbstractInterval}}} ) = LazyQuasiArrayStyle {2} ()
69
66
67
+
68
+ # ##
69
+ # Maps
70
+ # ##
71
+
72
+ # Affine map represents A*x .+ b
73
+ struct AffineQuasiVector{T,AA,X,B} <: AbstractQuasiVector{T}
74
+ A:: AA
75
+ x:: X
76
+ b:: B
77
+ end
78
+
79
+ AffineQuasiVector (A:: AA , x:: X , b:: B ) where {AA,X,B} =
80
+ AffineQuasiVector {promote_type(eltype(AA), eltype(X), eltype(B)),AA,X,B} (A,x,b)
81
+
82
+ AffineQuasiVector (A, x) = AffineQuasiVector (A, x, zero (promote_type (eltype (A),eltype (x))))
83
+ AffineQuasiVector (x) = AffineQuasiVector (one (eltype (x)), x)
84
+
85
+ AffineQuasiVector (A, x:: AffineQuasiVector , b) = AffineQuasiVector (A* x. A, x. x, A* x. b .+ b)
86
+
87
+ axes (A:: AffineQuasiVector ) = axes (A. x)
88
+ getindex (A:: AffineQuasiVector , k:: Number ) = A. A* A. x[k] .+ A. b
89
+ inbounds_getindex (A:: AffineQuasiVector{<:Any,<:Any,<:Inclusion} , k:: Number ) = A. A* k .+ A. b
90
+ isempty (A:: AffineQuasiVector ) = isempty (A. x)
91
+ == (a:: AffineQuasiVector , b:: AffineQuasiVector ) = a. A == b. A && a. x == b. x && a. b == b. b
92
+
93
+ BroadcastStyle (:: Type{<:AffineQuasiVector} ) = LazyQuasiArrayStyle {1} ()
94
+
95
+ for op in (:* , :\ , :+ , :- )
96
+ @eval broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof ($ op), a:: Number , x:: Inclusion ) = broadcast ($ op, a, AffineQuasiVector (x))
97
+ end
98
+ for op in (:/ , :+ , :- )
99
+ @eval broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof ($ op), x:: Inclusion , a:: Number ) = broadcast ($ op, AffineQuasiVector (x), a)
100
+ end
101
+
102
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (* ), a:: Number , x:: AffineQuasiVector ) = AffineQuasiVector (a, x)
103
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (\ ), a:: Number , x:: AffineQuasiVector ) = AffineQuasiVector (inv (a), x)
104
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (/ ), x:: AffineQuasiVector , a:: Number ) = AffineQuasiVector (inv (a), x)
105
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (+ ), a:: Number , x:: AffineQuasiVector ) = AffineQuasiVector (one (eltype (x)), x, a)
106
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (+ ), x:: AffineQuasiVector , b:: Number ) = AffineQuasiVector (one (eltype (x)), x, b)
107
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (- ), a:: Number , x:: AffineQuasiVector ) = AffineQuasiVector (- one (eltype (x)), x, a)
108
+ broadcasted (:: LazyQuasiArrayStyle{1} , :: typeof (- ), x:: AffineQuasiVector , b:: Number ) = AffineQuasiVector (one (eltype (x)), x, - b)
109
+
110
+ function checkindex (:: Type{Bool} , inds:: Inclusion{<:Any,<:AbstractInterval} , r:: AffineQuasiVector{<:Real,<:Real,<:Inclusion{<:Real,<:AbstractInterval}} )
111
+ @_propagate_inbounds_meta
112
+ isempty (r) | (checkindex (Bool, inds, first (r)) & checkindex (Bool, inds, last (r)))
113
+ end
114
+
115
+ for find in (:findfirst , :findlast , :findall )
116
+ @eval $ find (f:: Base.Fix2{typeof(isequal)} , d:: AffineQuasiVector ) = $ find (isequal (d. A \ (f. x .- d. b)), d. x)
117
+ end
118
+
119
+
120
+
121
+
70
122
include (" operators.jl" )
71
123
include (" bases/bases.jl" )
72
124
0 commit comments