@@ -42,30 +42,50 @@ function JacFunctionWrapper(f::F, fu_, u, p, t) where {F}
42
42
# The warning instead of error ensures a non-breaking change for users relying on an
43
43
# undefined / undocumented feature
44
44
fu = fu_ === nothing ? copy (u) : copy (fu_)
45
+
46
+ # Check this first else we were breaking things
47
+ # In the next breaking release, we will fix the ordering of the checks
48
+ iip = static_hasmethod (f, typeof ((fu, u)))
49
+ oop = static_hasmethod (f, typeof ((u,)))
50
+ if iip || oop
51
+ if p != = nothing || t != = nothing
52
+ Base. depwarn (""" `p` and/or `t` provided and are not `nothing`. But we
53
+ potentially detected `f(du, u)` or `f(u)`. This can be caused by:
54
+
55
+ 1. `f(du, u)` or `f(u)` is defined, in-which case `p` and/or `t` should not be
56
+ supplied.
57
+ 2. `f(args...)` is defined, in which case `hasmethod` can be spurious.
58
+
59
+ Currently, we perform the check for `f(du, u)` and `f(u)` first, but in future
60
+ breaking releases, this check will be performed last, which means that if `t`
61
+ is provided `f(du, u, p, t)`/`f(u, p, t)` will be given precedence, similarly
62
+ if `p` is provided `f(du, u, p)`/`f(u, p)` will be given precedence.""" ,
63
+ :JacFunctionWrapper )
64
+ end
65
+ return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
66
+ fu, p, t)
67
+ end
68
+
45
69
if t != = nothing
46
70
iip = static_hasmethod (f, typeof ((fu, u, p, t)))
47
71
oop = static_hasmethod (f, typeof ((u, p, t)))
48
72
if ! iip && ! oop
49
- @warn """ `p` and `t` provided but `f(u, p, t)` or `f(fu, u, p, t)` not defined
50
- for `f`! Will fallback to `f(u)` or `f(fu, u)`.""" maxlog= 1
51
- else
52
- return JacFunctionWrapper {iip, oop, 1, F, typeof(fu), typeof(p), typeof(t)} (f,
53
- fu, p, t)
73
+ throw (ArgumentError (""" `p` and `t` provided but `f(u, p, t)` or `f(fu, u, p, t)`
74
+ not defined for `f`!""" ))
54
75
end
55
- elseif p != = nothing && ! (p isa SciMLBase. NullParameters)
76
+ return JacFunctionWrapper {iip, oop, 1, F, typeof(fu), typeof(p), typeof(t)} (f,
77
+ fu, p, t)
78
+ elseif p != = nothing
56
79
iip = static_hasmethod (f, typeof ((fu, u, p)))
57
80
oop = static_hasmethod (f, typeof ((u, p)))
58
81
if ! iip && ! oop
59
- @warn """ `p` provided but `f(u, p)` or `f(fu, u, p)` not defined for `f`! Will
60
- fallback to `f(u)` or `f(fu, u)`.""" maxlog= 1
61
- else
62
- return JacFunctionWrapper {iip, oop, 2, F, typeof(fu), typeof(p), typeof(t)} (f,
63
- fu, p, t)
82
+ throw (ArgumentError (""" `p` is provided but `f(u, p)` or `f(fu, u, p)`
83
+ not defined for `f`!""" ))
64
84
end
85
+ return JacFunctionWrapper {iip, oop, 2, F, typeof(fu), typeof(p), typeof(t)} (f,
86
+ fu, p, t)
65
87
end
66
- iip = static_hasmethod (f, typeof ((fu, u)))
67
- oop = static_hasmethod (f, typeof ((u,)))
68
- ! iip && ! oop && throw (ArgumentError (" `f(u)` or `f(fu, u)` not defined for `f`" ))
69
- return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
70
- fu, p, t)
88
+
89
+ throw (ArgumentError (""" Couldn't determine the function signature of `f` to construct a
90
+ JacobianWrapper!""" ))
71
91
end
0 commit comments