Skip to content

Commit db664ed

Browse files
Merge pull request #3028 from ChrisRackauckas-Claude/tableau-tsit5-interp
Tableau implementation for Tsit5 with generic RK interpolation
2 parents 10501ef + a59462a commit db664ed

File tree

9 files changed

+719
-3
lines changed

9 files changed

+719
-3
lines changed

lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import OrdinaryDiffEqCore: alg_order, alg_adaptive_order, alg_stability_size,
66
unwrap_alg,
77
OrdinaryDiffEqMutableCache, initialize!, perform_step!, isfsal,
88
CompositeAlgorithm, calculate_residuals!, calculate_residuals,
9-
full_cache, get_fsalfirstlast
9+
full_cache, get_fsalfirstlast,
10+
_ode_interpolant, _ode_interpolant!,
11+
_ode_addsteps!, copyat_or_push!,
12+
DerivativeOrderNotPossibleError
1013
using TruncatedStacktraces: @truncate_stacktrace
1114
using RecursiveArrayTools, FastBroadcast, MuladdMacro, DiffEqBase
1215
import LinearAlgebra: norm
@@ -19,6 +22,8 @@ include("algorithms.jl")
1922
include("alg_utils.jl")
2023
include("explicit_rk_caches.jl")
2124
include("explicit_rk_perform_step.jl")
25+
include("inter_func.jl")
26+
include("interpolants.jl")
2227

2328
export ExplicitRK
2429

lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,223 @@ function constructDormandPrince(T::Type = Float64)
3636
)
3737
end
3838

39+
# ============================================================================
40+
# Tsit5 Interpolation Coefficients in Matrix Form
41+
# ============================================================================
42+
43+
"""
44+
construct_tsit5_interp_matrix(::Type{T}) where {T <: Union{Float32, Float64}}
45+
46+
Constructs the interpolation coefficient matrix for Tsit5 method.
47+
The matrix B_interp has dimensions (7, 5) where:
48+
- Row i contains coefficients for stage i's interpolation polynomial
49+
- Column j contains coefficients for Θ^(j-1) term
50+
"""
51+
function construct_tsit5_interp_matrix(::Type{T}) where {T <: Union{Float32, Float64}}
52+
r11 = convert(T, 1.0)
53+
r12 = convert(T, -2.763706197274826)
54+
r13 = convert(T, 2.9132554618219126)
55+
r14 = convert(T, -1.0530884977290216)
56+
57+
r22 = convert(T, 0.13169999999999998)
58+
r23 = convert(T, -0.2234)
59+
r24 = convert(T, 0.1017)
60+
61+
r32 = convert(T, 3.9302962368947516)
62+
r33 = convert(T, -5.941033872131505)
63+
r34 = convert(T, 2.490627285651253)
64+
65+
r42 = convert(T, -12.411077166933676)
66+
r43 = convert(T, 30.33818863028232)
67+
r44 = convert(T, -16.548102889244902)
68+
69+
r52 = convert(T, 37.50931341651104)
70+
r53 = convert(T, -88.1789048947664)
71+
r54 = convert(T, 47.37952196281928)
72+
73+
r62 = convert(T, -27.896526289197286)
74+
r63 = convert(T, 65.09189467479366)
75+
r64 = convert(T, -34.87065786149661)
76+
77+
r72 = convert(T, 1.5)
78+
r73 = convert(T, -4.0)
79+
r74 = convert(T, 2.5)
80+
81+
B_interp = zeros(T, 7, 5)
82+
B_interp[1, :] = [0, r11, r12, r13, r14]
83+
B_interp[2, :] = [0, 0, r22, r23, r24]
84+
B_interp[3, :] = [0, 0, r32, r33, r34]
85+
B_interp[4, :] = [0, 0, r42, r43, r44]
86+
B_interp[5, :] = [0, 0, r52, r53, r54]
87+
B_interp[6, :] = [0, 0, r62, r63, r64]
88+
B_interp[7, :] = [0, 0, r72, r73, r74]
89+
90+
return B_interp
91+
end
92+
93+
construct_tsit5_interp_matrix() = construct_tsit5_interp_matrix(Float64)
94+
95+
"""
96+
construct_tsit5_interp_matrix(::Type{T}) where T
97+
98+
High-precision version for BigFloat and other arbitrary-precision types.
99+
"""
100+
function construct_tsit5_interp_matrix(::Type{T}) where {T}
101+
r11 = convert(T, big"0.999999999999999974283372471559910888475488471328")
102+
r12 = convert(T, big"-2.763706197274825911336735930481400260916070804192")
103+
r13 = convert(T, big"2.91325546182191274375068099306808")
104+
r14 = convert(T, -1.0530884977290216)
105+
106+
r22 = convert(T, big"0.13169999999999999727")
107+
r23 = convert(T, big"-0.22339999999999999818")
108+
r24 = convert(T, 0.1017)
109+
110+
r32 = convert(T, big"3.93029623689475152850687446709813398")
111+
r33 = convert(T, big"-5.94103387213150473470249202589458001")
112+
r34 = convert(T, big"2.490627285651252793")
113+
114+
r42 = convert(T, big"-12.411077166933676983734381540685453484102414134010752")
115+
r43 = convert(T, big"30.3381886302823215981729903691836576")
116+
r44 = convert(T, big"-16.54810288924490272")
117+
118+
r52 = convert(T, big"37.50931341651103919496903965334519631242339792120440212")
119+
r53 = convert(T, big"-88.1789048947664011014276693541209817")
120+
r54 = convert(T, big"47.37952196281928122")
121+
122+
r62 = convert(T, big"-27.896526289197287805948263144598643896")
123+
r63 = convert(T, big"65.09189467479367152629021928716553658")
124+
r64 = convert(T, big"-34.87065786149660974")
125+
126+
r72 = convert(T, 1.5)
127+
r73 = convert(T, -4.0)
128+
r74 = convert(T, 2.5)
129+
130+
B_interp = zeros(T, 7, 5)
131+
B_interp[1, :] = [0, r11, r12, r13, r14]
132+
B_interp[2, :] = [0, 0, r22, r23, r24]
133+
B_interp[3, :] = [0, 0, r32, r33, r34]
134+
B_interp[4, :] = [0, 0, r42, r43, r44]
135+
B_interp[5, :] = [0, 0, r52, r53, r54]
136+
B_interp[6, :] = [0, 0, r62, r63, r64]
137+
B_interp[7, :] = [0, 0, r72, r73, r74]
138+
139+
return B_interp
140+
end
141+
142+
# ============================================================================
143+
# Tsit5 in ExplicitRK tableau format
144+
# ============================================================================
145+
146+
"""
147+
constructTsit5ExplicitRK(::Type{T}) where {T <: Union{Float32, Float64}}
148+
149+
Constructs the Tsitouras 5/4 method in ExplicitRK tableau format with compiled float coefficients.
150+
"""
151+
function constructTsit5ExplicitRK(::Type{T}) where {T <: Union{Float32, Float64}}
152+
A = [
153+
0.0 0.0 0.0 0.0 0.0 0.0 0.0
154+
0.161 0.0 0.0 0.0 0.0 0.0 0.0
155+
-0.008480655492356989 0.335480655492357 0.0 0.0 0.0 0.0 0.0
156+
2.8971530571054935 -6.359448489975075 4.3622954328695815 0.0 0.0 0.0 0.0
157+
5.325864828439257 -11.748883564062828 7.4955393428898365 -0.09249506636175525 0.0 0.0 0.0
158+
5.86145544294642 -12.92096931784711 8.159367898576159 -0.071584973281401 -0.028269050394068383 0.0 0.0
159+
0.09646076681806523 0.01 0.4798896504144996 1.379008574103742 -3.290069515436081 2.324710524099774 0.0
160+
]
161+
162+
c = [0.0, 0.161, 0.327, 0.9, 0.9800255409045097, 1.0, 1.0]
163+
164+
α = [
165+
0.09468075576583945, 0.009183565540343254, 0.4877705284247616,
166+
1.234297566930479, -2.7077123499835256, 1.866628418170587,
167+
0.015151515151515152,
168+
]
169+
170+
btilde = [
171+
-0.00178001105222577714, -0.0008164344596567469, 0.007880878010261995,
172+
-0.1447110071732629, 0.5823571654525552, -0.45808210592918697,
173+
0.015151515151515152,
174+
]
175+
176+
αEEst = α .- btilde
177+
178+
A = map(T, A)
179+
α = map(T, α)
180+
αEEst = map(T, αEEst)
181+
c = map(T, c)
182+
B_interp = construct_tsit5_interp_matrix(T)
183+
184+
return DiffEqBase.ExplicitRKTableau(
185+
A, c, α, 5,
186+
αEEst = αEEst,
187+
adaptiveorder = 4,
188+
fsal = true,
189+
stability_size = 2.9,
190+
B_interp = B_interp
191+
)
192+
end
193+
194+
constructTsit5ExplicitRK() = constructTsit5ExplicitRK(Float64)
195+
196+
"""
197+
constructTsit5ExplicitRK(::Type{T}) where T
198+
199+
High-precision version for BigFloat and other arbitrary-precision types.
200+
"""
201+
function constructTsit5ExplicitRK(::Type{T}) where {T}
202+
A = [
203+
0 0 0 0 0 0 0
204+
14 // 87 0 0 0 0 0 0
205+
-1 // 117 50 // 149 0 0 0 0 0
206+
310 // 107 -407 // 64 301 // 69 0 0 0 0
207+
474 // 89 -2479 // 211 817 // 109 -5 // 54 0 0 0
208+
381 // 65 -491 // 38 563 // 69 -19 // 265 -3 // 106 0 0
209+
8 // 83 1 // 100 107 // 223 131 // 95 -329 // 100 179 // 77 0
210+
]
211+
212+
c = [
213+
0; 161 // 1000; 327 // 1000; 9 // 10;
214+
big".9800255409045096857298102862870245954942137979563024768854764293221195950761080302604";
215+
1; 1
216+
]
217+
218+
α = [
219+
big".9468075576583945807478876255758922856117527357724631226139574065785592789071067303271e-1",
220+
big".9183565540343253096776363936645313759813746240984095238905939532922955247253608687270e-2",
221+
big".4877705284247615707855642599631228241516691959761363774365216240304071651579571959813",
222+
big"1.234297566930478985655109673884237654035539930748192848315425833500484878378061439761",
223+
big"-2.707712349983525454881109975059321670689605166938197378763992255714444407154902012702",
224+
big"1.866628418170587035753719399566211498666255505244122593996591602841258328965767580089",
225+
1 // 66,
226+
]
227+
228+
btilde = [
229+
big"-1.780011052225771443378550607539534775944678804333659557637450799792588061629796e-03",
230+
big"-8.164344596567469032236360633546862401862537590159047610940604670770447527463931e-04",
231+
big"7.880878010261996010314727672526304238628733777103128603258129604952959142646516e-03",
232+
big"-1.44711007173262907537165147972635116720922712343167677619514233896760819649515e-01",
233+
big"5.823571654525552250199376106520421794260781239567387797673045438803694038950012e-01",
234+
big"-4.580821059291869466616365188325542974428047279788398179474684434732070620889539e-01",
235+
1 // 66,
236+
]
237+
238+
αEEst = α .- btilde
239+
240+
A = map(T, A)
241+
α = map(T, α)
242+
αEEst = map(T, αEEst)
243+
c = map(T, c)
244+
B_interp = construct_tsit5_interp_matrix(T)
245+
246+
return DiffEqBase.ExplicitRKTableau(
247+
A, c, α, 5,
248+
αEEst = αEEst,
249+
adaptiveorder = 4,
250+
fsal = true,
251+
stability_size = 2.9,
252+
B_interp = B_interp
253+
)
254+
end
255+
39256
"""
40257
ODE_DEFAULT_TABLEAU
41258

lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,30 @@ function alg_cache(
3737
return ExplicitRKCache(u, uprev, tmp, utilde, atmp, fsalfirst, fsallast, kk, tab)
3838
end
3939

40-
struct ExplicitRKConstantCache{MType, VType, KType} <: OrdinaryDiffEqConstantCache
40+
struct ExplicitRKConstantCache{MType, VType, KType, BType, BiType} <:
41+
OrdinaryDiffEqConstantCache
4142
A::MType
4243
c::VType
4344
α::VType
4445
αEEst::VType
4546
stages::Int
4647
kk::KType
48+
B_interp::BType
49+
bi::BiType # Pre-allocated buffer for interpolation polynomial weights
4750
end
4851

4952
function ExplicitRKConstantCache(tableau, rate_prototype)
5053
(; A, c, α, αEEst, stages) = tableau
5154
A = copy(A') # Transpose A to column major looping
5255
kk = Array{typeof(rate_prototype)}(undef, stages) # Not ks since that's for integrator.opts.dense
5356
αEEst = isempty(αEEst) ? αEEst : α .- αEEst
54-
return ExplicitRKConstantCache(A, c, α, αEEst, stages, kk)
57+
B_interp = hasproperty(tableau, :B_interp) ? tableau.B_interp : nothing
58+
bi = if isnothing(B_interp)
59+
nothing
60+
else
61+
Vector{eltype(B_interp)}(undef, size(B_interp, 1))
62+
end
63+
return ExplicitRKConstantCache(A, c, α, αEEst, stages, kk, B_interp, bi)
5564
end
5665

5766
function alg_cache(

0 commit comments

Comments
 (0)