@@ -17,52 +17,56 @@ checkbounds(A::AbstractDerivativeOperator, k::Colon, j::Integer) =
1717checkbounds (A:: AbstractDerivativeOperator , k:: Integer , j:: Colon ) =
1818 (0 < k ≤ size (A, 1 ) || throw (BoundsError (A, (k,size (A,2 )))))
1919
20- # ~~ getindex ~~
2120@inline function getindex (A:: AbstractDerivativeOperator , i:: Int , j:: Int )
2221 @boundscheck checkbounds (A, i, j)
23- mid = div (A. stencil_length, 2 ) + 1
24- bpc = A. stencil_length - mid
25- l = max (1 , low (j, mid, bpc))
26- h = min (A. stencil_length, high (j, mid, bpc, A. stencil_length, A. dimension))
27- slen = h - l + 1
28- if abs (i - j) > div (slen, 2 )
29- return 0
22+ bpc = A. boundary_point_count
23+ N = A. len
24+ bsl = A. boundary_stencil_length
25+ slen = A. stencil_length
26+ if bpc > 0 && 1 <= i<= bpc
27+ if j > bsl
28+ return 0
29+ else
30+ return A. low_boundary_coefs[i][j]
31+ end
32+ elseif bpc > 0 && (N- bpc)< i<= N
33+ if j < N+ 2 - bsl
34+ return 0
35+ else
36+ return A. high_boundary_coefs[bpc- (N- i)][bsl- (N+ 2 - j)]
37+ end
3038 else
31- return A. stencil_coefs[mid + j - i]
39+ if j < i- bpc || j > i+ slen- bpc- 1
40+ return 0
41+ else
42+ return A. stencil_coefs[j- i + 1 + bpc]
43+ end
3244 end
3345end
3446
3547# scalar - colon - colon
36- @inline getindex (A:: AbstractDerivativeOperator , kr :: Colon , jr :: Colon ) = convert ( Array, A)
48+ @inline getindex (A:: AbstractDerivativeOperator , :: Colon , :: Colon ) = Array ( A)
3749
38- @inline function getindex (A:: AbstractDerivativeOperator , rc:: Colon , j)
39- T = eltype (A. stencil_coefs)
40- v = zeros (T, A. dimension)
41- v[j] = one (T)
42- copyto! (v, A* v)
43- return v
50+ @inline function getindex (A:: AbstractDerivativeOperator , :: Colon , j)
51+ return BandedMatrix (A)[:,j]
4452end
4553
4654
4755# symmetric right now
48- @inline function getindex (A:: AbstractDerivativeOperator , i, cc:: Colon )
49- T = eltype (A. stencil_coefs)
50- v = zeros (T, A. dimension)
51- v[i] = one (T)
52- copyto! (v, A* v)
53- return v
56+ @inline function getindex (A:: AbstractDerivativeOperator , i, :: Colon )
57+ return BandedMatrix (A)[i,:]
5458end
5559
5660
5761# UnitRanges
58- @inline function getindex (A:: AbstractDerivativeOperator , rng:: UnitRange{Int} , cc :: Colon )
59- m = convert (Array, A)
62+ @inline function getindex (A:: AbstractDerivativeOperator , rng:: UnitRange{Int} , :: Colon )
63+ m = BandedMatrix ( A)
6064 return m[rng, cc]
6165end
6266
6367
64- @inline function getindex (A:: AbstractDerivativeOperator , rc :: Colon , rng:: UnitRange{Int} )
65- m = convert (Array, A)
68+ @inline function getindex (A:: AbstractDerivativeOperator , :: Colon , rng:: UnitRange{Int} )
69+ m = BandedMatrix ( A)
6670 return m[rnd, cc]
6771end
6872
7983
8084
8185@inline function getindex (A:: AbstractDerivativeOperator{T} , rng:: UnitRange{Int} , cng:: UnitRange{Int} ) where T
82- N = A. dimension
83- if (rng[end ] - rng[1 ]) > ((cng[end ] - cng[1 ]))
84- mat = zeros (T, (N, length (cng)))
85- v = zeros (T, N)
86- for i = cng
87- v[i] = one (T)
88- #=
89- calculating the effect on a unit vector to get the matrix of transformation
90- to get the vector in the new vector space.
91- =#
92- mul! (view (mat, :, i - cng[1 ] + 1 ), A, v)
93- v[i] = zero (T)
94- end
95- return mat[rng, :]
96-
97- else
98- mat = zeros (T, (length (rng), N))
99- v = zeros (T, N)
100- for i = rng
101- v[i] = one (T)
102- #=
103- calculating the effect on a unit vector to get the matrix of transformation
104- to get the vector in the new vector space.
105- =#
106- mul! (view (mat, i - rng[1 ] + 1 , :), A, v)
107- v[i] = zero (T)
108- end
109- return mat[:, cng]
110- end
86+ return BandedMatrix (A)[rng,cng]
11187end
11288
11389#=
@@ -126,74 +102,95 @@ function LinearAlgebra.mul!(x_temp::AbstractArray{T,2}, A::AbstractDerivativeOpe
126102 end
127103end
128104
129-
130105# Base.length(A::AbstractDerivativeOperator) = A.stencil_length
131106Base. ndims (A:: AbstractDerivativeOperator ) = 2
132- Base. size (A:: AbstractDerivativeOperator ) = (A. dimension , A. dimension )
107+ Base. size (A:: AbstractDerivativeOperator ) = (A. len , A. len + 2 )
133108Base. size (A:: AbstractDerivativeOperator ,i:: Integer ) = size (A)[i]
134109Base. length (A:: AbstractDerivativeOperator ) = reduce (* , size (A))
135110
136-
137111#=
138112 For the evenly spaced grid we have a symmetric matrix
139113=#
140- Base. transpose (A:: Union{ DerivativeOperator,UpwindOperator} ) = A
141- Base. adjoint (A:: Union{ DerivativeOperator,UpwindOperator} ) = A
142- LinearAlgebra. issymmetric (:: Union{ DerivativeOperator,UpwindOperator} ) = true
114+ Base. transpose (A:: DerivativeOperator ) = A
115+ Base. adjoint (A:: DerivativeOperator ) = A
116+ LinearAlgebra. issymmetric (:: DerivativeOperator ) = true
143117
144118#=
145119 Fallback methods that use the full representation of the operator
146120=#
147- Base. exp (A:: AbstractDerivativeOperator{T} ) where T = exp (convert (Array, A))
121+ Base. exp (A:: AbstractDerivativeOperator{T} ) where T = exp (convert (A))
148122Base.:\ (A:: AbstractVecOrMat , B:: AbstractDerivativeOperator ) = A \ convert (Array,B)
149- Base.:\ (A:: AbstractDerivativeOperator , B:: AbstractVecOrMat ) = convert ( Array, A) \ B
123+ Base.:\ (A:: AbstractDerivativeOperator , B:: AbstractVecOrMat ) = Array ( A) \ B
150124Base.:/ (A:: AbstractVecOrMat , B:: AbstractDerivativeOperator ) = A / convert (Array,B)
151- Base.:/ (A:: AbstractDerivativeOperator , B:: AbstractVecOrMat ) = convert ( Array, A) / B
125+ Base.:/ (A:: AbstractDerivativeOperator , B:: AbstractVecOrMat ) = Array ( A) / B
152126
153- # #######################################################################
127+ #=
128+ The Inf opnorm can be calculated easily using the stencil coeffiicents, while other opnorms
129+ default to compute from the full matrix form.
130+ =#
131+ function LinearAlgebra. opnorm (A:: DerivativeOperator , p:: Real = 2 )
132+ if p == Inf
133+ sum (abs .(A. stencil_coefs)) / A. dx^ A. derivative_order
134+ else
135+ opnorm (BandedMatrix (A), p)
136+ end
137+ end
154138
155- # Are these necessary?
139+ # #######################################################################
156140
157141get_type (:: AbstractDerivativeOperator{T} ) where {T} = T
158142
159143function * (A:: AbstractDerivativeOperator ,x:: AbstractVector )
160- #=
161- We will output a vector which is a supertype of the types of A and x
162- to ensure numerical stability
163- =#
164- get_type (A) != eltype (x) ? error (" DiffEqOperator and array are not of same type!" ) : nothing
165- y = zeros (promote_type (eltype (A),eltype (x)), length (x))
144+ y = zeros (promote_type (eltype (A),eltype (x)), length (x)- 2 )
166145 LinearAlgebra. mul! (y, A:: AbstractDerivativeOperator , x:: AbstractVector )
167146 return y
168147end
169148
170149
171150function * (A:: AbstractDerivativeOperator ,M:: AbstractMatrix )
172- #=
173- We will output a vector which is a supertype of the types of A and x
174- to ensure numerical stability
175- =#
176- get_type (A) != eltype (M) ? error (" DiffEqOperator and array are not of same type!" ) : nothing
177- y = zeros (promote_type (eltype (A),eltype (M)), size (M))
151+ y = zeros (promote_type (eltype (A),eltype (M)), size (A,1 ), size (M,2 ))
178152 LinearAlgebra. mul! (y, A:: AbstractDerivativeOperator , M:: AbstractMatrix )
179153 return y
180154end
181155
182156
183157function * (M:: AbstractMatrix ,A:: AbstractDerivativeOperator )
184- #=
185- We will output a vector which is a supertype of the types of A and x
186- to ensure numerical stability
187- =#
188- get_type (A) != eltype (M) ? error (" DiffEqOperator and array are not of same type!" ) : nothing
189- y = zeros (promote_type (eltype (A),eltype (M)), size (M))
190- LinearAlgebra. mul! (y, A:: AbstractDerivativeOperator , M:: AbstractMatrix )
158+ y = zeros (promote_type (eltype (A),eltype (M)), size (M,1 ), size (A,2 ))
159+ LinearAlgebra. mul! (y, M, BandedMatrix (A))
191160 return y
192161end
193162
194163
195164function * (A:: AbstractDerivativeOperator ,B:: AbstractDerivativeOperator )
196- # TODO : it will result in an operator which calculates
197- # the derivative of order A.dorder + B.dorder of
198- # approximation_order = min(approx_A, approx_B)
165+ return BandedMatrix (A)* BandedMatrix (B)
166+ end
167+
168+ # ###############################################################################
169+
170+ function * (coeff_func:: Function , A:: DerivativeOperator{T,N,Wind} ) where {T,N,Wind}
171+ coefficients = A. coefficients === nothing ? Vector {T} (undef,A. len) : A. coefficients
172+ DerivativeOperator{T,N,Wind,typeof (A. dx),typeof (A. stencil_coefs),
173+ typeof (A. low_boundary_coefs),typeof (coefficients),
174+ typeof (coeff_func)}(
175+ A. derivative_order, A. approximation_order,
176+ A. dx, A. len, A. stencil_length,
177+ A. stencil_coefs,
178+ A. boundary_stencil_length,
179+ A. boundary_point_count,
180+ A. low_boundary_coefs,
181+ A. high_boundary_coefs,coefficients,coeff_func
182+ )
199183end
184+
185+ # ###############################################################################
186+
187+ function DiffEqBase. update_coefficients! (A:: AbstractDerivativeOperator ,u,p,t)
188+ if A. coeff_func != = nothing
189+ A. coeff_func (A. coefficients,u,p,t)
190+ end
191+ end
192+
193+ # ###############################################################################
194+
195+ (L:: DerivativeOperator )(u,p,t) = L* u
196+ (L:: DerivativeOperator )(du,u,p,t) = mul! (du,L,u)
0 commit comments