Skip to content

Commit 302f91f

Browse files
RomeoVclaude
andcommitted
Add downstream ODE solution recursivecopy tests
- Test recursivecopy with ODE solutions and ArrayPartition integration - Verify struct-based parameter copying in differential equations - Ensure deep independence of copied solution objects 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 148265e commit 302f91f

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using OrdinaryDiffEq, RecursiveArrayTools, Test
2+
3+
@testset "ODE Solution recursivecopy tests" begin
4+
5+
@testset "Basic ODE solution copying" begin
6+
# Define a simple ODE system
7+
function simple_ode!(du, u, p, t)
8+
du[1] = -0.5 * u[1]
9+
du[2] = 0.3 * u[2]
10+
end
11+
12+
u0 = [1.0, 2.0]
13+
tspan = (0.0, 2.0)
14+
prob = ODEProblem(simple_ode!, u0, tspan)
15+
sol = solve(prob, Tsit5(), saveat=0.5)
16+
17+
# Test that we can copy the solution
18+
copied_sol = recursivecopy(sol)
19+
20+
# Verify the solution structure is preserved
21+
@test typeof(copied_sol) == typeof(sol)
22+
@test copied_sol.t == sol.t
23+
@test copied_sol.u == sol.u
24+
@test copied_sol.retcode == sol.retcode
25+
26+
# Verify that arrays are independent copies
27+
@test copied_sol !== sol
28+
@test copied_sol.u !== sol.u
29+
@test copied_sol.t !== sol.t
30+
31+
# Test that modifying one doesn't affect the other
32+
if length(copied_sol.u) > 0
33+
original_value = sol.u[1][1]
34+
copied_sol.u[1][1] = 999.0
35+
@test sol.u[1][1] == original_value # Original should be unchanged
36+
end
37+
end
38+
39+
@testset "ArrayPartition ODE solution copying" begin
40+
# Use the Lorenz system from the existing tests
41+
function lorenz!(du, u, p, t)
42+
du.x[1][1] = 10.0 * (u.x[2][1] - u.x[1][1])
43+
du.x[1][2] = u.x[1][1] * (28.0 - u.x[2][1]) - u.x[1][2]
44+
du.x[2][1] = u.x[1][1] * u.x[1][2] - (8/3) * u.x[2][1]
45+
end
46+
47+
u0 = ArrayPartition([1.0, 0.0], [0.0])
48+
tspan = (0.0, 1.0)
49+
prob = ODEProblem(lorenz!, u0, tspan)
50+
sol = solve(prob, Tsit5(), saveat=0.2)
51+
52+
# Test that we can copy the ArrayPartition-based solution
53+
copied_sol = recursivecopy(sol)
54+
55+
# Verify solution structure
56+
@test typeof(copied_sol) == typeof(sol)
57+
@test copied_sol.t == sol.t
58+
@test length(copied_sol.u) == length(sol.u)
59+
60+
# Verify ArrayPartition structure is preserved
61+
for i in eachindex(sol.u)
62+
@test copied_sol.u[i] isa ArrayPartition
63+
@test copied_sol.u[i].x[1] == sol.u[i].x[1]
64+
@test copied_sol.u[i].x[2] == sol.u[i].x[2]
65+
66+
# Verify independence
67+
@test copied_sol.u[i] !== sol.u[i]
68+
@test copied_sol.u[i].x[1] !== sol.u[i].x[1]
69+
@test copied_sol.u[i].x[2] !== sol.u[i].x[2]
70+
end
71+
end
72+
73+
@testset "Struct-based parameter copying in ODE" begin
74+
# Create an ODE with struct-based parameters to test our struct copying
75+
struct ODEParams
76+
decay_rate::Float64
77+
growth_rate::Float64
78+
coefficients::Vector{Float64}
79+
end
80+
81+
function parametric_ode!(du, u, params::ODEParams, t)
82+
du[1] = -params.decay_rate * u[1] + params.coefficients[1]
83+
du[2] = params.growth_rate * u[2] + params.coefficients[2]
84+
end
85+
86+
params = ODEParams(0.5, 0.3, [0.1, 0.2])
87+
u0 = [1.0, 2.0]
88+
tspan = (0.0, 1.0)
89+
prob = ODEProblem(parametric_ode!, u0, tspan, params)
90+
sol = solve(prob, Tsit5(), saveat=0.5)
91+
92+
# Test copying the solution (which contains the struct parameters)
93+
copied_sol = recursivecopy(sol)
94+
95+
# Verify parameter struct is copied correctly
96+
@test copied_sol.prob.p isa ODEParams
97+
@test copied_sol.prob.p.decay_rate == sol.prob.p.decay_rate
98+
@test copied_sol.prob.p.growth_rate == sol.prob.p.growth_rate
99+
@test copied_sol.prob.p.coefficients == sol.prob.p.coefficients
100+
101+
# Verify independence
102+
@test copied_sol.prob.p !== sol.prob.p
103+
@test copied_sol.prob.p.coefficients !== sol.prob.p.coefficients
104+
105+
# Test that modifying copied parameters doesn't affect original
106+
copied_sol.prob.p.coefficients[1] = 999.0
107+
@test sol.prob.p.coefficients[1] == 0.1 # Original unchanged
108+
end
109+
110+
println("All ODE solution recursivecopy tests completed successfully!")
111+
end

0 commit comments

Comments
 (0)