Skip to content

Commit 1c19498

Browse files
committed
Rank of laguerre coefficients in constructor, fixes #4
The coefficient-rank in the Weeks{T}-type is no longer declared explicitly. Instead, it is supplied as an argument to the outer constructor. Array- and complex-tests have been reformatted and grouped into testsets.
1 parent 005feac commit 1c19498

File tree

3 files changed

+102
-65
lines changed

3 files changed

+102
-65
lines changed

src/weeks.jl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ mutable struct Weeks{T} <: AbstractWeeks
1515
Nterms::Int
1616
sigma::Float64
1717
b::Float64
18-
coefficients::Array{T,1}
18+
coefficients::Array{T}
1919
end
2020

2121
function _get_coefficients(func, Nterms, sigma, b, ::Type{T}) where T <:Number
@@ -36,6 +36,7 @@ _get_array_coefficients(w::Weeks{T}) where T <: Number = _get_array_coefficients
3636
#_set_array_coefficients(w::Weeks) = (w.coefficients = _get_coefficients(w))
3737

3838
const weeks_default_num_terms = 64
39+
const weeks_default_ndims = 0
3940

4041
"""
4142
w::Weeks{datatype} = Weeks(func::Function, Nterms::Integer=64, sigma=1.0, b=1.0; datatype=Float64)
@@ -59,14 +60,25 @@ julia> ft(pi/2)
5960
```
6061
"""
6162
function Weeks(func::Function, Nterms::Integer=weeks_default_num_terms,
62-
sigma=1.0, b=1.0; datatype=Float64)
63+
sigma=1.0, b=1.0; datatype=Float64,rank::Integer=weeks_default_ndims)
6364
outdatatype = datatype == Complex ? Complex{Float64} : datatype # allow `Complex` as abbrev for Complex{Float64}
64-
return Weeks{outdatatype}(func, Nterms, sigma, b, _get_coefficients(func, Nterms, sigma, b, outdatatype))
65+
if rank == 0
66+
# Use scalar-functionality
67+
return Weeks{outdatatype}(func, Nterms, sigma, b, _get_coefficients(func, Nterms, sigma, b, outdatatype))
68+
else
69+
# Use array-functionality
70+
return Weeks{outdatatype}(func, Nterms, sigma, b, _get_array_coefficients(func, Nterms, sigma, b, outdatatype))
71+
end
6572
end
6673

6774
function eval_ilt(w::Weeks, t)
68-
L = _laguerre(w.coefficients, 2 * w.b * t)
69-
return L * exp((w.sigma - w.b) * t)
75+
coeffs = w.coefficients
76+
if ndims(coeffs)==1
77+
L = _laguerre(coeffs, 2 * w.b * t)
78+
else
79+
L = reshape(mapslices(i -> _laguerre(i,2 * w.b * t),coeffs,dims=(1)),size(coeffs)[2:end])
80+
end
81+
return L .* exp((w.sigma - w.b) * t)
7082
end
7183

7284
function eval_ilt(w::Weeks, t::AbstractArray)

test/arrayweeks_test.jl

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,80 @@ function Fcomplex(s)
1111
return 1 / (s - α)
1212
end
1313

14-
# Test scalar-functionality of arrcoeff, Fcomplex=(s-a)⁻¹
15-
let arr = try InverseLaplace._arrcoeff(Fcomplex,4,1.0,1.0);
16-
InverseLaplace._arrcoeff(Fcomplex,4,1.0,1.0)
17-
catch
18-
InverseLaplace._arrcoeff(Fcomplex,4,1.0,1.0)
19-
end, scal = InverseLaplace._wcoeff(Fcomplex,4,1.0,1.0)
14+
@testset "Array functionality" begin
15+
@testset "Internal functions" begin
16+
# Test scalar-functionality of arrcoeff, Fcomplex=(s-a)⁻¹
17+
let arr = try InverseLaplace._arrcoeff(Fcomplex,4,1.0,1.0);
18+
InverseLaplace._arrcoeff(Fcomplex,4,1.0,1.0)
19+
catch
20+
InverseLaplace._arrcoeff(Fcomplex,4,1.0,1.0)
21+
end, scal = InverseLaplace._wcoeff(Fcomplex,4,1.0,1.0)
2022

21-
@test arr == scal
22-
end
23-
24-
# Test for ordering of array valued coefficients (along first dimension)
25-
let arr = try InverseLaplace._arrcoeff(arrFcomplex,4,1.0,1.0);
26-
InverseLaplace._arrcoeff(arrFcomplex,4,1.0,1.0)
27-
catch
28-
InverseLaplace._arrcoeff(arrFcomplex,4,1.0,1.0)
29-
end, scal = InverseLaplace._wcoeff(Fcomplex,4,1.0,1.0)
30-
@test arr[:,1,1] == scal
31-
@test arr[:,1,2] == 2 .* arr[:,1,1]
32-
@test isapprox(arr[:,2,1] , 3 .* arr[:,1,1], atol=1E-15)
33-
@test arr[:,2,2] == 4 .* arr[:,1,1]
34-
end
23+
@test arr == scal
24+
end
3525

36-
# Compare _get_coefficients and _laguerre for array functions and scalar functions
37-
let arr = try InverseLaplace._get_array_coefficients(arrFcomplex,4,1.0,1.0,Complex);
38-
InverseLaplace._get_array_coefficients(arrFcomplex,4,1.0,1.0,Complex)
39-
catch
40-
InverseLaplace._get_array_coefficients(arrFcomplex,4,1.0,1.0,Complex)
41-
end, scal = InverseLaplace._get_coefficients(Fcomplex,4,1.0,1.0,Complex)
42-
@test arr[:,1,1] == scal
43-
@test arr[:,1,2] == 2 .* scal
44-
@test isapprox(arr[:,2,1] , 3 .* scal, atol=1E-15)
45-
@test arr[:,2,2] == 4 .* scal
46-
47-
laguerreeval = reshape(mapslices(i -> InverseLaplace._laguerre(i,1.0),arr,dims=(1)),(2,2))
48-
@test isapprox(laguerreeval, [1 2; 3 4] .* InverseLaplace._laguerre(scal,1.0), atol = 1E-15)
49-
end
26+
# Test for ordering of array valued coefficients (along first dimension)
27+
let arr = try InverseLaplace._arrcoeff(arrFcomplex,4,1.0,1.0);
28+
InverseLaplace._arrcoeff(arrFcomplex,4,1.0,1.0)
29+
catch
30+
InverseLaplace._arrcoeff(arrFcomplex,4,1.0,1.0)
31+
end, scal = InverseLaplace._wcoeff(Fcomplex,4,1.0,1.0)
32+
@test arr[:,1,1] == scal
33+
@test arr[:,1,2] == 2 .* arr[:,1,1]
34+
@test isapprox(arr[:,2,1] , 3 .* arr[:,1,1], atol=1E-15)
35+
@test arr[:,2,2] == 4 .* arr[:,1,1]
36+
end
5037

38+
# Compare _get_coefficients and _laguerre for array functions and scalar functions
39+
let arr = try InverseLaplace._get_array_coefficients(arrFcomplex,4,1.0,1.0,Complex);
40+
InverseLaplace._get_array_coefficients(arrFcomplex,4,1.0,1.0,Complex)
41+
catch
42+
InverseLaplace._get_array_coefficients(arrFcomplex,4,1.0,1.0,Complex)
43+
end, scal = InverseLaplace._get_coefficients(Fcomplex,4,1.0,1.0,Complex)
44+
@test arr[:,1,1] == scal
45+
@test arr[:,1,2] == 2 .* scal
46+
@test isapprox(arr[:,2,1] , 3 .* scal, atol=1E-15)
47+
@test arr[:,2,2] == 4 .* scal
5148

49+
laguerreeval = reshape(mapslices(i -> InverseLaplace._laguerre(i,1.0),arr,dims=(1)),(2,2))
50+
@test isapprox(laguerreeval, [1 2; 3 4] .* InverseLaplace._laguerre(scal,1.0), atol = 1E-15)
51+
end
52+
end
53+
@testset "ILT for arrays" begin
54+
# Test the ILT calculation for arrays and compare with the scalar Weeks method
55+
let
56+
# Weeks parameters
57+
N = 4
58+
σ = 1.0
59+
b = 0.5
60+
t = 1.0
61+
testingrank = 2
62+
funcdims = size(arrFcomplex(rand(Complex{Float64}))) # (2,2)
5263

53-
# Test the ILT calculation for arrays and compare with the scalar Weeks method
54-
let
55-
# Weeks parameters
56-
σ = 1.0
57-
b = 0.5
58-
t = 1.0
64+
# Evaluating ILT for array valued function
65+
coef = InverseLaplace._get_array_coefficients(arrFcomplex,4,σ,b,Complex)
66+
lag = reshape(mapslices(i -> InverseLaplace._laguerre(i,2 * b * t),coef,dims=(1)),(2,2))
67+
inverse = lag .* exp((σ - b) * t)
5968

60-
# Evaluating ILT for array valued function
61-
coef = InverseLaplace._get_array_coefficients(arrFcomplex,4,σ,b,Complex)
62-
lag = reshape(mapslices(i -> InverseLaplace._laguerre(i,2 * b * t),coef,dims=(1)),(2,2))
63-
inverse = lag .* exp((σ - b) * t)
69+
# Evaluating ILT for scalar function, then multiplying by an array
70+
Ft = Weeks(Fcomplex,4,σ,b,datatype=Complex)
71+
Ft_array_eval = [1 2;3 4] .* Ft(1.0)
6472

65-
# Evaluating ILT for scalar function, then multiplying by an array
66-
Ft = Weeks(Fcomplex,4,σ,b,datatype=Complex)
67-
Ft_array_eval = [1 2;3 4] .* Ft(1.0)
73+
@test isapprox(Ft_array_eval , inverse, atol=1E-15)
6874

69-
@test isapprox(Ft_array_eval , inverse, atol=1E-15)
75+
# Test the array constructor for Weeks{T}, both real and complex
76+
Arr_c = Weeks(arrFcomplex,N,σ,b,datatype=Complex,rank=testingrank)
77+
Scal_c = Weeks(Fcomplex,N,σ,b,datatype=Complex)
78+
Arr_r = Weeks(arrFcomplex,N,σ,b,rank=testingrank)
79+
Scal_r = Weeks(Fcomplex,N,σ,b)
80+
@test ndims(Arr_c.coefficients) == testingrank + 1
81+
@test size(Arr_c.coefficients) == (Arr_c.Nterms, 2,2)
82+
@test ndims(Arr_r.coefficients) == testingrank + 1
83+
@test size(Arr_r.coefficients) == (Arr_r.Nterms,2,2)
84+
@test real(Arr_c.coefficients) == Arr_r.coefficients
85+
@test isapprox(Arr_c(t),[1 2; 3 4] .* Scal_c(t),atol=1E-15)
86+
@test isapprox(Arr_r(t),[1 2; 3 4] .* Scal_r(t),atol=1E-15)
87+
@test isapprox(real(Arr_c(t)),Arr_r(t),atol=1E-15)
88+
end
89+
end
7090
end

test/weeks_test.jl

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,24 @@ setparameters(fle,2.0,2.0,80)
4343
@test c1 != fle.coefficients
4444

4545
### Complex
46+
@testset "Complex-functionality" begin
47+
function Fcomplex(s)
48+
# Laplace domain
49+
α = complex(-0.3, 6.0)
50+
return 1 / (s - α)
51+
end
4652

47-
function Fcomplex(s)
48-
# Laplace domain
49-
α = complex(-0.3, 6.0)
50-
return 1 / (s - α)
51-
end
53+
function fcomplex(t)
54+
# Time domain
55+
α = complex(-0.3, 6.0)
56+
return exp* t)
57+
end
5258

53-
function fcomplex(t)
54-
# Time domain
55-
α = complex(-0.3, 6.0)
56-
return exp* t)
57-
end
59+
let
60+
Fc = Weeks(Fcomplex, 256, 1.0, 10.0, datatype=Complex), trange = range(0.0, stop=15.0, length=5)
61+
@test isapprox(Fc.(trange), fcomplex.(trange), atol=0.0001)
5862

59-
let Fc = Weeks(Fcomplex, 256, 1.0, 10.0, datatype=Complex), trange = range(0.0, stop=15.0, length=5)
60-
@test isapprox(Fc.(trange), fcomplex.(trange), atol=0.0001)
63+
Fr = Weeks(Fcomplex, 256, 1.0, 10.0)
64+
@test real(Fc.(trange)) == Fr.(trange)
65+
end
6166
end

0 commit comments

Comments
 (0)