Skip to content
This repository was archived by the owner on Jul 19, 2023. It is now read-only.

Commit 7f6b2b2

Browse files
Merge remote-tracking branch 'origin/master'
2 parents 47b7868 + 05eca93 commit 7f6b2b2

File tree

5 files changed

+82
-37
lines changed

5 files changed

+82
-37
lines changed

Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1010
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1111
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1212
SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
13+
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
1314

1415
[compat]
1516
julia = "1"

src/DiffEqOperators.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Base: +, -, *, /, \, size, getindex, setindex!, Matrix, convert
44
using DiffEqBase, StaticArrays, LinearAlgebra
55
import LinearAlgebra: mul!, ldiv!, lmul!, rmul!, axpy!, opnorm, factorize, I
66
import DiffEqBase: AbstractDiffEqLinearOperator, update_coefficients!, is_constant
7-
using SparseArrays, ForwardDiff
7+
using SparseArrays, ForwardDiff, BandedMatrices
88

99
abstract type AbstractDerivativeOperator{T} <: AbstractDiffEqLinearOperator{T} end
1010
abstract type AbstractDiffEqCompositeOperator{T} <: AbstractDiffEqLinearOperator{T} end
@@ -30,6 +30,7 @@ include("derivative_operators/derivative_irreg_operator.jl")
3030
include("derivative_operators/derivative_operator.jl")
3131
include("derivative_operators/abstract_operator_functions.jl")
3232
include("derivative_operators/convolutions.jl")
33+
include("derivative_operators/concretization.jl")
3334

3435
### Composite Operators
3536
include("composite_operators.jl")
Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,57 @@
1-
function Base.convert(::Type{Array}, A::AbstractDerivativeOperator{T}, N::Int=A.dimension) where T
2-
@assert N >= A.stencil_length # stencil must be able to fit in the matrix
3-
mat = zeros(T, (N, N+2))
4-
v = zeros(T, N+2)
5-
for i=1:N+2
6-
v[i] = one(T)
7-
#=
8-
calculating the effect on a unit vector to get the matrix of transformation
9-
to get the vector in the new vector space.
10-
=#
11-
mul!(view(mat,:,i), A, v)
12-
v[i] = zero(T)
13-
end
14-
return mat
1+
function LinearAlgebra.Array(A::DerivativeOperator{T}) where T
2+
N = A.dimension
3+
L = zeros(T, N, N+2)
4+
bl = A.boundary_length
5+
stl = A.stencil_length
6+
stl_2 = div(stl,2)
7+
for i in 1:A.boundary_length
8+
L[i,1:stl] = A.low_boundary_coefs[i]
9+
end
10+
for i in bl+1:N-bl
11+
L[i,i+1-stl_2:i+1+stl_2] = A.stencil_coefs
12+
end
13+
for i in N-bl+1:N
14+
L[i,N-stl+3:N+2] = A.high_boundary_coefs[i-N+bl]
15+
end
16+
return L / A.dx^A.derivative_order
1517
end
1618

17-
function SparseArrays.sparse(A::AbstractDerivativeOperator{T}) where T
19+
function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T}) where T
1820
N = A.dimension
19-
mat = spzeros(T, N, N)
20-
v = zeros(T, N)
21-
row = zeros(T, N)
22-
for i=1:N
23-
v[i] = one(T)
24-
#=
25-
calculating the effect on a unit vector to get the matrix of transformation
26-
to get the vector in the new vector space.
27-
=#
28-
mul!(row, A, v)
29-
copyto!(view(mat,:,i), row)
30-
@. row = 0 * row;
31-
v[i] = zero(T)
32-
end
33-
return mat
21+
L = spzeros(T, N, N+2)
22+
bl = A.boundary_length
23+
stl = A.stencil_length
24+
stl_2 = div(stl,2)
25+
for i in 1:A.boundary_length
26+
L[i,1:stl] = A.low_boundary_coefs[i]
27+
end
28+
for i in bl+1:N-bl
29+
L[i,i+1-stl_2:i+1+stl_2] = A.stencil_coefs
30+
end
31+
for i in N-bl+1:N
32+
L[i,N-stl+3:N+2] = A.high_boundary_coefs[i-N+bl]
33+
end
34+
return L / A.dx^A.derivative_order
3435
end
3536

36-
# BandedMatrix{A,B,C,D}(A::DerivativeOperator{A,B,C,D}) = BandedMatrix(convert(Array, A, A.stencil_length), A.stencil_length, div(A.stencil_length,2), div(A.stencil_length,2))
37+
function SparseArrays.sparse(A::AbstractDerivativeOperator{T}) where T
38+
SparseMatrixCSC(A)
39+
end
40+
41+
function BandedMatrices.BandedMatrix(A::DerivativeOperator{T}) where T
42+
N = A.dimension
43+
bl = A.boundary_length
44+
stl = A.stencil_length
45+
stl_2 = div(stl,2)
46+
L = BandedMatrix{T}(Zeros(N, N+2), (max(stl-3,0),max(stl-1,0)))
47+
for i in 1:A.boundary_length
48+
L[i,1:stl] = A.low_boundary_coefs[i]
49+
end
50+
for i in bl+1:N-bl
51+
L[i,i+1-stl_2:i+1+stl_2] = A.stencil_coefs
52+
end
53+
for i in N-bl+1:N
54+
L[i,N-stl+3:N+2] = A.high_boundary_coefs[i-N+bl]
55+
end
56+
return L / A.dx^A.derivative_order
57+
end

src/derivative_operators/convolutions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function convolve_BC_right!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::
3737
coeffs = A.high_boundary_coefs
3838
Threads.@threads for i in 1 : A.boundary_length
3939
xtempi = coeffs[i][end]*x[end]
40-
@inbounds for idx in A.stencil_length:-1:1
40+
@inbounds for idx in A.stencil_length-1:-1:1
4141
xtempi += coeffs[i][end-idx] * x[end-idx]
4242
end
4343
x_temp[end-A.boundary_length+i] = xtempi

test/derivative_operators_interface.jl

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using SparseArrays, DiffEqOperators, LinearAlgebra, Random, Test
1+
using SparseArrays, DiffEqOperators, LinearAlgebra, Random, Test, BandedMatrices
22

33
function second_derivative_stencil(N)
44
A = zeros(N,N+2)
@@ -30,15 +30,37 @@ end
3030
N = 10
3131
d_order = 2
3232
approx_order = 2
33-
x = collect(1:1.0:N).^2
3433
correct = second_derivative_stencil(N)
3534
A = DerivativeOperator{Float64}(d_order,approx_order,1.0,N)
3635

3736
@test convert_by_multiplication(Array,A,N) == correct
38-
@test_broken convert(Array, A, N) == second_derivative_stencil(N)
39-
@test_broken sparse(A) == second_derivative_stencil(N)
37+
@test Array(A) == second_derivative_stencil(N)
38+
@test sparse(A) == second_derivative_stencil(N)
39+
@test BandedMatrix(A) == second_derivative_stencil(N)
4040
@test_broken opnorm(A, Inf) == opnorm(correct, Inf)
4141

42+
43+
# testing higher derivative and approximation concretization
44+
N = 20
45+
d_order = 4
46+
approx_order = 4
47+
A = DerivativeOperator{Float64}(d_order,approx_order,1.0,N)
48+
correct = convert_by_multiplication(Array,A,N)
49+
50+
@test Array(A) == correct
51+
@test sparse(A) == correct
52+
@test BandedMatrix(A) == correct
53+
54+
N = 40
55+
d_order = 8
56+
approx_order = 8
57+
A = DerivativeOperator{Float64}(d_order,approx_order,1.0,N)
58+
correct = convert_by_multiplication(Array,A,N)
59+
60+
@test Array(A) == correct
61+
@test sparse(A) == correct
62+
@test BandedMatrix(A) == correct
63+
4264
# testing correctness of multiplication
4365
N = 1000
4466
d_order = 4

0 commit comments

Comments
 (0)