1
- using ContinuumArrays, LazyArrays, IntervalSets
2
- import ContinuumArrays: AbstractAxisMatrix, ℵ₀
1
+ using ContinuumArrays, LazyArrays, IntervalSets, FillArrays, LinearAlgebra, Test
2
+ import ContinuumArrays: AbstractAxisMatrix, ℵ₀, materialize
3
3
import Base: axes, getindex, convert
4
4
5
5
struct Spline{order,T} <: AbstractAxisMatrix{T}
@@ -11,7 +11,7 @@ const HeavisideSpline{T} = Spline{0,T}
11
11
12
12
Spline {o} (pts:: AbstractVector{T} ) where {o,T} = Spline {o,float(T)} (pts)
13
13
14
- axes (B:: Spline{o} ) where o = (first (B. points).. last (B. points), Base. OneTo (length (B. points)- o- 1 ))
14
+ axes (B:: Spline{o} ) where o = (first (B. points).. last (B. points), Base. OneTo (length (B. points)+ o- 1 ))
15
15
16
16
function getindex (B:: LinearSpline{T} , x:: Real , k:: Int ) where T
17
17
x ∈ axes (B,1 ) && 1 ≤ k ≤ size (B,2 )|| throw (BoundsError ())
@@ -37,34 +37,83 @@ function getindex(B::HeavisideSpline{T}, x::Real, k::Int) where T
37
37
return one (T)
38
38
end
39
39
40
- # getindex(B::LinearSpline, ::Colon, k::Int) = Mul(B, [Zeros{Int}(k-1); 1; Zeros{Int}(size(B,2)-k)])
41
40
42
- # function convert(::Type{SymTridiagonal}, AB::Mul{<:Any,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:LinearSpline},<:LinearSpline})
43
- # Ac,B = AB.A, AB.B
44
- # A = parent(Ac)
45
- # @assert A.points == B.points
46
- # x = A.points
47
- # SymTridiagonal(x, x/2) # TODO fix
48
- # end
41
+ function convert (:: Type{SymTridiagonal} , AB:: Mul{T,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:LinearSpline},<:LinearSpline} ) where T
42
+ Ac,B = AB. A, AB. B
43
+ A = parent (Ac)
44
+ @assert A. points == B. points
45
+ x = A. points; n = length (x)
46
+ dv = Vector {T} (undef, n)
47
+ dv[1 ] = (x[2 ]- x[1 ])/ 3
48
+ for k = 2 : n- 1
49
+ dv[k] = (x[k+ 1 ]- x[k- 1 ])/ 3
50
+ end
51
+ dv[n] = (x[n] - x[n- 1 ])/ 3
52
+
53
+ SymTridiagonal (dv, diff (x)./ 6 )
54
+ end
49
55
#
50
- # materialize(M::Mul{<:Any,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:LinearSpline},<:LinearSpline}) =
51
- # convert(SymTridiagonal, M)
56
+ materialize (M:: Mul{<:Any,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:LinearSpline},<:LinearSpline} ) =
57
+ convert (SymTridiagonal, M)
58
+
59
+ function materialize (M:: Mul{T,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:HeavisideSpline},<:HeavisideSpline} ) where T
60
+ Ac, B = M. A, M. B
61
+ axes (Ac,2 ) == axes (B,1 ) || throw (DimensionMismatch (" axes must be same" ))
62
+ A = parent (Ac)
63
+ A. points == B. points || throw (ArgumentError (" Cannot multiply incompatible splines" ))
64
+ Diagonal (diff (A. points))
65
+ end
66
+
52
67
53
68
# # tests
54
69
55
- B = HeavisideSpline ([1 ,2 ,3 ])
56
- @test size (B) == (ℵ₀, 2 )
70
+ H = HeavisideSpline ([1 ,2 ,3 ])
71
+ @test size (H) == (ℵ₀, 2 )
72
+
73
+ @test_throws BoundsError H[0.1 , 1 ]
74
+ @test H[1.1 ,1 ] === H' [1 ,1.1 ] === transpose (H)[1 ,1.1 ] === 1.0
75
+ @test H[2.1 ,1 ] === H' [1 ,2.1 ] === transpose (H)[1 ,2.1 ] === 0.0
76
+ @test H[1.1 ,2 ] === 0.0
77
+ @test H[2.1 ,2 ] === 1.0
78
+ @test_throws BoundsError H[2.1 ,3 ]
79
+ @test_throws BoundsError H' [3 ,2.1 ]
80
+ @test_throws BoundsError transpose (H)[3 ,2.1 ]
81
+ @test_throws BoundsError H[3.1 ,2 ]
82
+
83
+ @test all (H[[1.1 ,2.1 ], 1 ] .=== H' [1 ,[1.1 ,2.1 ]] .=== transpose (H)[1 ,[1.1 ,2.1 ]] .=== [1.0 ,0.0 ])
84
+ @test all (H[1.1 ,1 : 2 ] .=== [1.0 ,0.0 ])
85
+ @test all (H[[1.1 ,2.1 ], 1 : 2 ] .=== [1.0 0.0 ; 0.0 1.0 ])
86
+
87
+ @test_throws BoundsError H[[0.1 ,2.1 ], 1 ]
88
+
89
+
90
+ L = LinearSpline ([1 ,2 ,3 ])
91
+ @test size (L) == (ℵ₀, 3 )
92
+
93
+ @test_throws BoundsError L[0.1 , 1 ]
94
+ @test L[1.1 ,1 ] == L' [1 ,1.1 ] == transpose (L)[1 ,1.1 ] ≈ 0.9
95
+ @test L[2.1 ,1 ] === L' [1 ,2.1 ] === transpose (L)[1 ,2.1 ] === 0.0
96
+ @test L[1.1 ,2 ] ≈ 0.1
97
+ @test L[2.1 ,2 ] ≈ 0.9
98
+ @test L[2.1 ,3 ] == L' [3 ,2.1 ] == transpose (L)[3 ,2.1 ] ≈ 0.1
99
+ @test_throws BoundsError L[3.1 ,2 ]
100
+ L[[1.1 ,2.1 ], 1 ]
101
+ @test L[[1.1 ,2.1 ], 1 ] == L' [1 ,[1.1 ,2.1 ]] == transpose (L)[1 ,[1.1 ,2.1 ]] ≈ [0.9 ,0.0 ]
102
+ @test L[1.1 ,1 : 2 ] ≈ [0.9 ,0.1 ]
103
+ @test L[[1.1 ,2.1 ], 1 : 2 ] ≈ [0.9 0.1 ; 0.0 0.9 ]
104
+
105
+ @test_throws BoundsError L[[0.1 ,2.1 ], 1 ]
106
+
57
107
58
- @test_throws BoundsError B[0.1 , 1 ]
59
- @test B[1.1 ,1 ] === 1.0
60
- @test B[2.1 ,1 ] === 0.0
61
- @test B[1.1 ,2 ] === 0.0
62
- @test B[2.1 ,2 ] === 1.0
63
- @test_throws BoundsError B[2.1 ,3 ]
64
- @test_throws BoundsError B[3.1 ,2 ]
108
+ f = H* [1 ,2 ]
109
+ @test axes (f) == (1.0 .. 3.0 ,)
110
+ @test f[1.1 ] ≈ 1
111
+ @test f[2.1 ] ≈ 2
65
112
66
- @test all (B[[1.1 ,2.1 ], 1 ] .=== [1.0 ,0.0 ])
67
- @test all (B[1.1 ,1 : 2 ] .=== [1.0 ,0.0 ])
68
- @test all (B[[1.1 ,2.1 ], 1 : 2 ] .=== [1.0 0.0 ; 0.0 1.0 ])
113
+ f = L* [1 ,2 ,4 ]
114
+ @test axes (f) == (1.0 .. 3.0 ,)
115
+ @test f[1.1 ] ≈ 1.1
116
+ @test f[2.1 ] ≈ 2.2
69
117
70
- @test_throws BoundsError B[[0.1 ,2.1 ], 1 ]
118
+ @test H' H == Eye (2 )
119
+ @test L' L == SymTridiagonal ([1 / 3 ,2 / 3 ,1 / 3 ], [1 / 6 ,1 / 6 ])
0 commit comments