Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 270 additions & 0 deletions src/matlab.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
#=
Copyright (c) 2015, Roberto Garrappa
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution
* Neither the name of the Department of Mathematics - University of Bari - Italy nor the names
of its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
=#

function mittleff_matlab(α,β,γ,z)
(α,β,γ,z)=promote(α,β,γ,z)
T=typeof(α)
if real(α)<=0 || real(γ)<=0 || !isreal(α) || !isreal(β) || !isreal(γ)
ArgumentError("Error in the parameters of the Mittag-Leffler function. α($α) and γ($γ) must be real and positive. β($β) must be real.")

Check warning on line 35 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L31-L35

Added lines #L31 - L35 were not covered by tests
end
if abs(γ-1) > eps(T)
if α>1
ArgumentError("With the three parameters Mittag-Leffler function, the parameter α($α) must satisfy 0<α<1.")

Check warning on line 39 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L37-L39

Added lines #L37 - L39 were not covered by tests
end
if abs(angle(z*(abs(z)>eps(T)))) <= α*π
ArgumentError("With the three parameters Mittag-Leffler function, this code works only when |arg(z)|>απ. z=$z")

Check warning on line 42 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L41-L42

Added lines #L41 - L42 were not covered by tests
end
end
ϵ=10*eps(T)
if abs(z)<ϵ
return 1/gamma(β)

Check warning on line 47 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L45-L47

Added lines #L45 - L47 were not covered by tests
else
return LTInversion(one(z),z,α,β,γ,ϵ)

Check warning on line 49 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L49

Added line #L49 was not covered by tests
end
end
mittleff_matlab(α,β,z)=mittleff_matlab(α,β,1,z)
mittleff_matlab(α,z)=mittleff_matlab(α,1,z);

Check warning on line 53 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L52-L53

Added lines #L52 - L53 were not covered by tests

function LTInversion(t,λ,α,β,γ,ϵ)
T=typeof(λ)

Check warning on line 56 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L55-L56

Added lines #L55 - L56 were not covered by tests

# Evaluation of the relevant poles
θ = angle(λ)
kmin = ceil(-α/2-θ/2/π)
kmax = floor(α/2-θ/2/π)
k_vett = kmin:kmax
s_star = abs(λ)^(1/α)*exp.(1im*(θ.+2π*k_vett)./α)

Check warning on line 63 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L59-L63

Added lines #L59 - L63 were not covered by tests

# Evaluation of ϕ(s_star) for each pole
ϕ_s_star = (real.(s_star)+abs.(s_star))/2

Check warning on line 66 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L66

Added line #L66 was not covered by tests

# Sorting of the poles according to the value of ϕ(s_star)
index_s_star = sortperm(ϕ_s_star)
ϕ_s_star = ϕ_s_star[index_s_star]
s_star = s_star[index_s_star]

Check warning on line 71 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L69-L71

Added lines #L69 - L71 were not covered by tests

# Deleting possible poles with ϕ_s_star=0
index_save = ϕ_s_star.>ϵ
s_star = s_star[index_save]
ϕ_s_star = ϕ_s_star[index_save]

Check warning on line 76 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L74-L76

Added lines #L74 - L76 were not covered by tests

# Inserting the origin in the set of the singularities
s_star = vcat(0,s_star)
ϕ_s_star = vcat(0,ϕ_s_star)
J1 = length(s_star); J=J1-1

Check warning on line 81 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L79-L81

Added lines #L79 - L81 were not covered by tests

# Strength of the singularities
p = vcat(max(0,-2*(α*γ-β+1)), fill(γ,(J,)))
q = vcat(fill(γ,(J,)), T(Inf))
append!(ϕ_s_star, T(Inf))

Check warning on line 86 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L84-L86

Added lines #L84 - L86 were not covered by tests

# Looking for the admissible regions with respect to round-off errors
admissible_regions = findall((ϕ_s_star[1:end-1].<(log(ϵ)-log(eps(T)))/t) .& (ϕ_s_star[1:end-1].<ϕ_s_star[2:end]))

Check warning on line 89 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L89

Added line #L89 was not covered by tests

# Initializing vectors for optimal parameters
JJ1 = admissible_regions[end]
μ_vett = fill(T(Inf),JJ1)
N_vett = fill(T(Inf),JJ1)
h_vett = fill(T(Inf),JJ1)

Check warning on line 95 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L92-L95

Added lines #L92 - L95 were not covered by tests

# Evaluation of parameters for inversion of LT in each admissible region
find_region=false
while !find_region
for j1 = admissible_regions
if j1<J1
(μj,hj,Nj) = OptimalParam_RB(t,ϕ_s_star[j1],ϕ_s_star[j1+1],p[j1],q[j1],ϵ)

Check warning on line 102 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L98-L102

Added lines #L98 - L102 were not covered by tests
else
(μj,hj,Nj) = OptimalParam_RU(t,ϕ_s_star[j1],p[j1],ϵ)

Check warning on line 104 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L104

Added line #L104 was not covered by tests
end
μ_vett[j1]=μj; h_vett[j1]=hj; N_vett[j1]=Nj
end
if minimum(N_vett)>200
ϵ *= 10

Check warning on line 109 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L106-L109

Added lines #L106 - L109 were not covered by tests
else
find_region = true

Check warning on line 111 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L111

Added line #L111 was not covered by tests
end
end

Check warning on line 113 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L113

Added line #L113 was not covered by tests

# Selection of the admissible region for integration which involves the minimum number of nodes
(N,iN)=findmin(N_vett); μ=μ_vett[iN]; h=h_vett[iN]

Check warning on line 116 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L116

Added line #L116 was not covered by tests

# Evaluation of the inverse Laplace transform
k=-N:N; u=h*k
z = μ*(im*u.+1).^2
zd = -2*μ*u .+ 2im*μ
zexp = exp.(t*z)
F = z.^(α*γ-β) ./ (z.^α.-λ).^γ .* zd
S = zexp .* F;
Integral = h*sum(S)/(2*im*π);

Check warning on line 125 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L119-L125

Added lines #L119 - L125 were not covered by tests

# Evaluation of residues
ss_star = s_star[iN+1:end];
Residues = sum(1/α * ss_star.^(1-β) .* exp.(t*ss_star));

Check warning on line 129 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L128-L129

Added lines #L128 - L129 were not covered by tests

# Evaluation of the ML function
E = Integral + Residues;
if isreal(λ)
E = real(E)

Check warning on line 134 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L132-L134

Added lines #L132 - L134 were not covered by tests
end
return E;

Check warning on line 136 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L136

Added line #L136 was not covered by tests
end

function OptimalParam_RB(t,ϕ_s_star_j,ϕ_s_star_j1,pj,qj,ϵ)

Check warning on line 139 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L139

Added line #L139 was not covered by tests
# Definition of some constants
T=typeof(t); fac=1.01; conservative_error_analysis=false;

Check warning on line 141 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L141

Added line #L141 was not covered by tests

# Maximum value of fbar as the ration between tolerance and round-off unit
f_max = ϵ/eps(T);

Check warning on line 144 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L144

Added line #L144 was not covered by tests

# Evaluation of the starting values for sq_ϕ_star_j and sq_ϕ_star_j1
sq_ϕ_star_j = sqrt(ϕ_s_star_j);
threshold = 2*sqrt(log(f_max)/t);
sq_ϕ_star_j1 = min(sqrt(ϕ_s_star_j1), threshold-sq_ϕ_star_j);

Check warning on line 149 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L147-L149

Added lines #L147 - L149 were not covered by tests

# Zero or negative values of pj and qj
if pj<10*ϵ && qj<10*ϵ
sq_φ_star_j=sq_ϕ_star_j; sq_φ_star_j1=sq_ϕ_star_j1; adm_region=true;

Check warning on line 153 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L152-L153

Added lines #L152 - L153 were not covered by tests
# Zero or negative values of just pj
elseif pj<10*ϵ && qj>=10*ϵ
sq_φ_star_j=sq_ϕ_star_j;
if sq_ϕ_star_j>0
f_min = fac*(sq_ϕ_star_j/(sq_ϕ_star_j1-sq_ϕ_star_j))^qj

Check warning on line 158 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L155-L158

Added lines #L155 - L158 were not covered by tests
else
f_min = fac;

Check warning on line 160 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L160

Added line #L160 was not covered by tests
end
if f_min<f_max
f_bar = f_min+f_min/f_max*(f_max-f_min);
fq = f_bar^(-1/qj);
sq_φ_star_j1 = (2*sq_ϕ_star_j1-fq*sq_ϕ_star_j)/(2+fq);
adm_region=true;

Check warning on line 166 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L162-L166

Added lines #L162 - L166 were not covered by tests
else
adm_region=false;

Check warning on line 168 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L168

Added line #L168 was not covered by tests
end
# Zero or negative values of just qj
elseif pj>=10*ϵ && qj<10*ϵ
sq_φ_star_j1=sq_ϕ_star_j1;
f_min = fac*(sq_ϕ_star_j1/(sq_ϕ_star_j1-sq_ϕ_star_j))^qj
if f_min<f_max
f_bar = f_min+f_min/f_max*(f_max-f_min);
fp = f_bar^(-1/pj);
sq_φ_star_j = (2*sq_ϕ_star_j+fp*sq_ϕ_star_j1)/(2-fp);
adm_region=true;

Check warning on line 178 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L171-L178

Added lines #L171 - L178 were not covered by tests
else
adm_region=false;

Check warning on line 180 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L180

Added line #L180 was not covered by tests
end
# Positive values of both pj and qj
elseif pj>=10*ϵ && qj>=10*ϵ
f_min = fac*(sq_ϕ_star_j+sq_ϕ_star_j1)/(sq_ϕ_star_j1-sq_ϕ_star_j)^max(pj,qj);
if f_min<f_max
f_min=max(f_min,1.5)
f_bar = f_min+f_min/f_max*(f_max-f_min);
fp = f_bar^(-1/pj);
fq = f_bar^(-1/qj);
if !conservative_error_analysis
w = -ϕ_s_star_j1*t/log(ϵ);

Check warning on line 191 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L183-L191

Added lines #L183 - L191 were not covered by tests
else
w = -2*ϕ_s_star_j1*t/(log(ϵ)-ϕ_s_star_j1*t)

Check warning on line 193 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L193

Added line #L193 was not covered by tests
end
den = 2+w-(1+w)*fp+fq;
sq_φ_star_j = ((2+w+fq)*sq_ϕ_star_j+fp*sq_ϕ_star_j1)/den;
sq_φ_star_j1 = (-(1+w)*fq*sq_ϕ_star_j+(2+w-(1+w)*fp)*sq_ϕ_star_j1)/den;
adm_region=true;

Check warning on line 198 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L195-L198

Added lines #L195 - L198 were not covered by tests
else
adm_region=false;

Check warning on line 200 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L200

Added line #L200 was not covered by tests
end
end

if adm_region
ϵ /= f_bar;
if !conservative_error_analysis
w = -sq_φ_star_j1^2*t/log(ϵ)

Check warning on line 207 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L204-L207

Added lines #L204 - L207 were not covered by tests
else
w = -2*sq_φ_star_j1^2*t/(log(ϵ)-sq_φ_star_j1^2*t)

Check warning on line 209 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L209

Added line #L209 was not covered by tests
end
μj = (((1+w)*sq_φ_star_j+sq_φ_star_j1)/(2+w))^2;
hj = -2π/log(ϵ)*(sq_φ_star_j1-sq_φ_star_j)/((1+w)*sq_φ_star_j+sq_φ_star_j1)
Nj = ceil(sqrt(1-log(ϵ)/t/μj)/hj);

Check warning on line 213 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L211-L213

Added lines #L211 - L213 were not covered by tests
else
μj=zero(T); hj=zero(T); Nj=T(Inf);

Check warning on line 215 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L215

Added line #L215 was not covered by tests
end
return (μj,hj,Nj)

Check warning on line 217 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L217

Added line #L217 was not covered by tests
end

function OptimalParam_RU(t,ϕ_s_star_j,pj,ϵ)

Check warning on line 220 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L220

Added line #L220 was not covered by tests
# Evaluation of the starting values for sq_phi_star_j
sq_ϕ_s_star_j=sqrt(ϕ_s_star_j)
if ϕ_s_star_j>0
φ_star_j=ϕ_s_star_j*1.01

Check warning on line 224 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L222-L224

Added lines #L222 - L224 were not covered by tests
else
φ_star_j=0.01;

Check warning on line 226 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L226

Added line #L226 was not covered by tests
end
sq_φ_star_j=sqrt(φ_star_j);

Check warning on line 228 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L228

Added line #L228 was not covered by tests

# Definition of some constants
f_min=1; f_max=10; f_tar=5;
T=typeof(t); log_ϵ=log(ϵ);

Check warning on line 232 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L231-L232

Added lines #L231 - L232 were not covered by tests

# Iterative process to look for fbar in [f_min,f_max]
stop=false; sq_μj=0; A=0;
while !stop
ϕ_t=φ_star_j*t; log_ϵ_ϕ_t=log_ϵ/ϕ_t;
Nj = ceil(ϕ_t/π*(1-3*log_ϵ_ϕ_t/2+sqrt(1-2*log_ϵ_ϕ_t)))
A = π*Nj/ϕ_t
sq_μj = sq_φ_star_j*abs(4-A)/abs(7-sqrt(1+12*A))
fbar = ((sq_φ_star_j-sq_ϕ_s_star_j)/sq_μj)^(-pj)
stop = (pj<10*ϵ) || (f_min<fbar && fbar<f_max)
if !stop
sq_φ_star_j = f_tar^(-1/pj)*sq_μj+sq_ϕ_s_star_j
φ_star_j = sq_φ_star_j^2

Check warning on line 245 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L235-L245

Added lines #L235 - L245 were not covered by tests
end
end
μj=sq_μj^2
hj = (-3*A-2+2*sqrt(1+12*A))/(4-A)/Nj;

Check warning on line 249 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L247-L249

Added lines #L247 - L249 were not covered by tests

# Adjusting integration parameters to keep round-off errors under control
log_eps=log(eps(T)); threshold=(log_ϵ-log_eps)/t;
if μj>threshold
if abs(pj)<10*ϵ
Q=0

Check warning on line 255 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L252-L255

Added lines #L252 - L255 were not covered by tests
else
Q=f_tar^(-1/pj)*sqrt(μj)

Check warning on line 257 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L257

Added line #L257 was not covered by tests
end
if φ_star_j<threshold
w = sqrt(log_eps/(log_eps-log_ϵ))
u = sqrt(-φ_star_j*t/log_eps)
μj= threshold
Nj= ceil(w*log_ϵ/(2π*(u*w-1)))
hj= w/Nj

Check warning on line 264 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L259-L264

Added lines #L259 - L264 were not covered by tests
else
Nj=T(Inf); hj=zero(T);

Check warning on line 266 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L266

Added line #L266 was not covered by tests
end
end
return (μj,hj,Nj)

Check warning on line 269 in src/matlab.jl

View check run for this annotation

Codecov / codecov/patch

src/matlab.jl#L269

Added line #L269 was not covered by tests
end