From 5c5f91f4c877691d7f0d92b27e2dbcc41d276d85 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 3 Sep 2023 06:57:06 -0400 Subject: [PATCH] Add a better error message for noise size incompatability ```julia using DifferentialEquations f(du, u, p, t) = du .= 1.01u function g(du, u, p, t) du[1, 1] = 0.3u[1] du[1, 2] = 0.6u[1] du[1, 3] = 0.9u[1] du[1, 4] = 0.12u[1] du[2, 1] = 1.2u[2] du[2, 2] = 0.2u[2] du[2, 3] = 0.3u[2] du[2, 4] = 1.8u[2] end prob = SDEProblem(f, g, randn(ComplexF64,2), (0.0, 1.0), noise_rate_prototype =complex(zeros(2, 4)),noise=RealWienerProcess(0.0,zeros(3))) sol = solve(prob) ``` ``` ERROR: Noise sizes are incompatible. The expected number of noise terms in the defined `noise_rate_prototype` does not match the number of noise terms in the defined `AbstractNoiseProcess`. Please ensure that size(prob.noise_rate_prototype,2) == length(prob.noise.W[1]). Note: Noise process definitions require that users specify `u0`, and this value is directly used in the definition. For example, if `noise = WienerProcess(0.0,0.0)`, then the noise process is a scalar with `u0=0.0`. If `noise = WienerProcess(0.0,[0.0])`, then the noise process is a vector with `u0=0.0`. If `noise_rate_prototype = zeros(2,4)`, then the noise process must be a 4-dimensional process, for example `noise = WienerProcess(0.0,zeros(4))`. This error is a sign that the user definition of `noise_rate_prototype` and `noise` are not aligned in this manner and the definitions should be double checked. size(prob.noise_rate_prototype,2) = 4 length(prob.noise.W[1]) = 3 ``` Should be a much better message for https://github.com/SciML/StochasticDiffEq.jl/issues/543 --- src/solve.jl | 25 +++++++++++++++++++++++++ test/downstream/solve_error_handling.jl | 17 ++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/solve.jl b/src/solve.jl index 47aca61df..cd2e656c4 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -187,6 +187,25 @@ function Base.showerror(io::IO, e::NonSolverError) println(io, TruncatedStacktraces.VERBOSE_MSG) end +const NOISE_SIZE_MESSAGE = """ + Noise sizes are incompatible. The expected number of noise terms in the defined + `noise_rate_prototype` does not match the number of noise terms in the defined + `AbstractNoiseProcess`. Please ensure that + size(prob.noise_rate_prototype,2) == length(prob.noise.W[1]). + """ + +struct NoiseSizeIncompatabilityError <: Exception + prototypesize::Int + noisesize::Int +end + +function Base.showerror(io::IO, e::NoiseSizeIncompatabilityError) + println(io, NOISE_SIZE_MESSAGE) + println(io, "size(prob.noise_rate_prototype,2) = $(e.prototypesize)") + println(io, "length(prob.noise.W[1]) = $(e.noisesize)") + println(io, TruncatedStacktraces.VERBOSE_MSG) +end + const PROBSOLVER_PAIRING_MESSAGE = """ Incompatible problem+solver pairing. For example, this can occur if an ODE solver is passed with an SDEProblem. @@ -1278,6 +1297,12 @@ function check_prob_alg_pairing(prob, alg) throw(DirectAutodiffError()) end + @show "here?" + + if prob isa SDEProblem && size(prob.noise_rate_prototype,2) != length(prob.noise.W[1]) + throw(NoiseSizeIncompatabilityError(size(prob.noise_rate_prototype,2), length(prob.noise.W[1]))) + end + # Complex number support comes before arbitrary number support for a more direct # error message. if !SciMLBase.allowscomplex(alg) diff --git a/test/downstream/solve_error_handling.jl b/test/downstream/solve_error_handling.jl index e9f0ee780..d9bf3c497 100644 --- a/test/downstream/solve_error_handling.jl +++ b/test/downstream/solve_error_handling.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test, Sundials +using OrdinaryDiffEq, StochasticDiffEq, Test, Sundials f(u, p, t) = 2u u0 = 0.5 @@ -48,3 +48,18 @@ fmm = ODEFunction((du, u, t) -> nothing, mass_matrix = zeros(0, 0)) prob = ODEProblem(fmm, nothing, (0.0, 1.0)) sol = solve(prob, Tsit5()) @test isa(sol, DiffEqBase.ODESolution) + +f(du, u, p, t) = du .= 1.01u +function g(du, u, p, t) + du[1, 1] = 0.3u[1] + du[1, 2] = 0.6u[1] + du[1, 3] = 0.9u[1] + du[1, 4] = 0.12u[1] + du[2, 1] = 1.2u[2] + du[2, 2] = 0.2u[2] + du[2, 3] = 0.3u[2] + du[2, 4] = 1.8u[2] +end + +prob = SDEProblem(f, g, randn(ComplexF64,2), (0.0, 1.0), noise_rate_prototype =complex(zeros(2, 4)),noise=RealWienerProcess(0.0,zeros(3))) +@test_throws DiffEqBase.NoiseSizeIncompatabilityError solve(prob, LambdaEM()) \ No newline at end of file