From 5c5f91f4c877691d7f0d92b27e2dbcc41d276d85 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 3 Sep 2023 06:57:06 -0400 Subject: [PATCH 1/7] 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 From b427c8768d7b657a304520a1a44fc6d658175ca5 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 3 Sep 2023 06:57:16 -0400 Subject: [PATCH 2/7] add some examples --- src/solve.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/solve.jl b/src/solve.jl index cd2e656c4..7b396741d 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -192,6 +192,15 @@ const NOISE_SIZE_MESSAGE = """ `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. """ struct NoiseSizeIncompatabilityError <: Exception From c1ce75d3c3e8e35e6155842422f8c25aa79fd2c2 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 3 Sep 2023 07:17:54 -0400 Subject: [PATCH 3/7] ensure that the noise fields are not nothing --- src/solve.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solve.jl b/src/solve.jl index 7b396741d..c86891626 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -1308,7 +1308,8 @@ function check_prob_alg_pairing(prob, alg) @show "here?" - if prob isa SDEProblem && size(prob.noise_rate_prototype,2) != length(prob.noise.W[1]) + if prob isa SDEProblem && noise_rate_prototype !=== nothing && + prob.noise !== nothing && 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 From c02adeab09fdeaf12c2f7b036159939716112667 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 3 Sep 2023 07:32:08 -0400 Subject: [PATCH 4/7] fix !=== --- src/solve.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solve.jl b/src/solve.jl index c86891626..970b9fe5f 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -1308,7 +1308,7 @@ function check_prob_alg_pairing(prob, alg) @show "here?" - if prob isa SDEProblem && noise_rate_prototype !=== nothing && + if prob isa SDEProblem && noise_rate_prototype !== nothing && prob.noise !== nothing && 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 From 4cfa2aa913f8bbc1b174b4696d00c253bfc22e62 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 3 Sep 2023 10:54:09 -0400 Subject: [PATCH 5/7] typo --- src/solve.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/solve.jl b/src/solve.jl index 970b9fe5f..d6637bd8c 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -1306,9 +1306,7 @@ function check_prob_alg_pairing(prob, alg) throw(DirectAutodiffError()) end - @show "here?" - - if prob isa SDEProblem && noise_rate_prototype !== nothing && + if prob isa SDEProblem && prob.noise_rate_prototype !== nothing && prob.noise !== nothing && 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 From 683ba5d6bf554e9b303cfa2c065a8847b72097ed Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sun, 3 Sep 2023 15:22:09 -0400 Subject: [PATCH 6/7] Update solve_error_handling.jl --- test/downstream/solve_error_handling.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/downstream/solve_error_handling.jl b/test/downstream/solve_error_handling.jl index d9bf3c497..3b6abe4ac 100644 --- a/test/downstream/solve_error_handling.jl +++ b/test/downstream/solve_error_handling.jl @@ -61,5 +61,5 @@ function g(du, u, p, t) 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 +prob = SDEProblem(f, g, randn(ComplexF64,2), (0.0, 1.0), noise_rate_prototype =complex(zeros(2, 4)),noise=StochasticDiffEq.RealWienerProcess(0.0,zeros(3))) +@test_throws DiffEqBase.NoiseSizeIncompatabilityError solve(prob, LambdaEM()) From f90ed8966f4968143e1df4d54147e03c3c73352d Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 4 Sep 2023 09:31:19 -0400 Subject: [PATCH 7/7] Update test/downstream/solve_error_handling.jl --- test/downstream/solve_error_handling.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/downstream/solve_error_handling.jl b/test/downstream/solve_error_handling.jl index 3b6abe4ac..12e8a79e2 100644 --- a/test/downstream/solve_error_handling.jl +++ b/test/downstream/solve_error_handling.jl @@ -62,4 +62,4 @@ function g(du, u, p, t) end prob = SDEProblem(f, g, randn(ComplexF64,2), (0.0, 1.0), noise_rate_prototype =complex(zeros(2, 4)),noise=StochasticDiffEq.RealWienerProcess(0.0,zeros(3))) -@test_throws DiffEqBase.NoiseSizeIncompatabilityError solve(prob, LambdaEM()) +@test_throws DiffEqBase.NoiseSizeIncompatabilityError solve(prob, LambaEM())