|
170 | 170 | @test get_parameter_values(b) == [1.0; 2.0] |
171 | 171 | @test last.(get_parameter_map(b)) == [1.0; 2.0] |
172 | 172 | end |
| 173 | + |
| 174 | +@testset "ODEProblem from Basis (Issue #559)" begin |
| 175 | + # Regression test for issue #559: solve throws MethodError when creating |
| 176 | + # ODEProblem from Basis due to symbolic to numeric conversion issues |
| 177 | + using OrdinaryDiffEqTsit5 |
| 178 | + |
| 179 | + # Create a simple basis with parameters that have no default values |
| 180 | + @variables u[1:2] |
| 181 | + @parameters w[1:2] |
| 182 | + u = collect(u) |
| 183 | + w = collect(w) |
| 184 | + |
| 185 | + # Create a basis with parameters without default values |
| 186 | + # This tests the zero(Symbolics.symtype(p)) code path |
| 187 | + h = [u[1]^2 + w[1] * u[2]; sin(w[2] * u[1])] |
| 188 | + basis = Basis(h, u, parameters = w) |
| 189 | + |
| 190 | + # Test that get_parameter_values returns unwrapped numeric values, not symbolic |
| 191 | + params = get_parameter_values(basis) |
| 192 | + @test params isa Vector |
| 193 | + @test all(p -> !(p isa Num), params) # Should not be Num/symbolic |
| 194 | + @test all(iszero, params) # Parameters without defaults should be zero |
| 195 | + |
| 196 | + # Test that get_parameter_map also returns unwrapped numeric values |
| 197 | + param_map = get_parameter_map(basis) |
| 198 | + @test all(pair -> !(last(pair) isa Num), param_map) |
| 199 | + |
| 200 | + # Test that we can create an ODEProblem from the basis |
| 201 | + # This is the key test from issue #559 - should not throw MethodError |
| 202 | + # about "Cannot convert BasicSymbolic{Real} to Float64" |
| 203 | + u0 = [1.0, 2.0] |
| 204 | + tspan = (0.0, 0.1) # Very short timespan |
| 205 | + p_values = [0.01, 0.01] # Very small parameter values |
| 206 | + recovered_model = ODEProblem(basis, u0, tspan, p_values) |
| 207 | + @test recovered_model isa ODEProblem |
| 208 | + |
| 209 | + # Test that we can initialize the integrator without the symbolic conversion error |
| 210 | + sol = solve(recovered_model, Tsit5(), save_everystep = false) |
| 211 | + |
| 212 | + # Also test with parameters that have default values |
| 213 | + @parameters w2[1:2] = [1.5, 2.5] |
| 214 | + w2 = collect(w2) |
| 215 | + h2 = [u[1]^2 + w2[1] * u[2]; sin(w2[2] * u[1])] |
| 216 | + basis2 = Basis(h2, u, parameters = w2) |
| 217 | + |
| 218 | + # Test that get_parameter_values returns the default values unwrapped |
| 219 | + params2 = get_parameter_values(basis2) |
| 220 | + @test all(p -> !(p isa Num), params2) |
| 221 | + @test params2 ≈ [1.5, 2.5] |
| 222 | + |
| 223 | + # Test creating ODEProblem with default parameter values |
| 224 | + recovered_model2 = ODEProblem(basis2, u0, tspan, params2) |
| 225 | + @test recovered_model2 isa ODEProblem |
| 226 | +end |
0 commit comments