@@ -38,34 +38,70 @@ __internal_oop(::JacFunctionWrapper{iip, oop}) where {iip, oop} = oop
38
38
(f:: JacFunctionWrapper{false, true, 2} )(u) = f. f (u, f. p)
39
39
(f:: JacFunctionWrapper{false, true, 3} )(u) = f. f (u)
40
40
41
- function JacFunctionWrapper (f:: F , fu_, u, p, t) where {F}
41
+ # NOTE: `use_deprecated_ordering` is a way for external libraries to update to the correct
42
+ # style. In the next release, we will drop the first check
43
+ function JacFunctionWrapper (f:: F , fu_, u, p, t;
44
+ use_deprecated_ordering:: Val{deporder} = Val (true )) where {F, deporder}
42
45
# The warning instead of error ensures a non-breaking change for users relying on an
43
46
# undefined / undocumented feature
44
47
fu = fu_ === nothing ? copy (u) : copy (fu_)
48
+
49
+ if deporder
50
+ # Check this first else we were breaking things
51
+ # In the next breaking release, we will fix the ordering of the checks
52
+ iip = static_hasmethod (f, typeof ((fu, u)))
53
+ oop = static_hasmethod (f, typeof ((u,)))
54
+ if iip || oop
55
+ if p != = nothing || t != = nothing
56
+ Base. depwarn (""" `p` and/or `t` provided and are not `nothing`. But we
57
+ potentially detected `f(du, u)` or `f(u)`. This can be caused by:
58
+
59
+ 1. `f(du, u)` or `f(u)` is defined, in-which case `p` and/or `t` should not
60
+ be supplied.
61
+ 2. `f(args...)` is defined, in which case `hasmethod` can be spurious.
62
+
63
+ Currently, we perform the check for `f(du, u)` and `f(u)` first, but in
64
+ future breaking releases, this check will be performed last, which means
65
+ that if `t` is provided `f(du, u, p, t)`/`f(u, p, t)` will be given
66
+ precedence, similarly if `p` is provided `f(du, u, p)`/`f(u, p)` will be
67
+ given precedence.""" , :JacFunctionWrapper )
68
+ end
69
+ return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
70
+ fu, p, t)
71
+ end
72
+ end
73
+
45
74
if t != = nothing
46
75
iip = static_hasmethod (f, typeof ((fu, u, p, t)))
47
76
oop = static_hasmethod (f, typeof ((u, p, t)))
48
77
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)
78
+ throw (ArgumentError (""" `p` and `t` provided but `f(u, p, t)` or `f(fu, u, p, t)`
79
+ not defined for `f`!""" ))
54
80
end
81
+ return JacFunctionWrapper {iip, oop, 1, F, typeof(fu), typeof(p), typeof(t)} (f,
82
+ fu, p, t)
55
83
elseif p != = nothing
56
84
iip = static_hasmethod (f, typeof ((fu, u, p)))
57
85
oop = static_hasmethod (f, typeof ((u, p)))
58
86
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)
87
+ throw (ArgumentError (""" `p` is provided but `f(u, p)` or `f(fu, u, p)`
88
+ not defined for `f`!""" ))
89
+ end
90
+ return JacFunctionWrapper {iip, oop, 2, F, typeof(fu), typeof(p), typeof(t)} (f,
91
+ fu, p, t)
92
+ end
93
+
94
+ if ! deporder
95
+ iip = static_hasmethod (f, typeof ((fu, u)))
96
+ oop = static_hasmethod (f, typeof ((u,)))
97
+ if ! iip && ! oop
98
+ throw (ArgumentError (""" `p` is provided but `f(u)` or `f(fu, u)` not defined for
99
+ `f`!""" ))
64
100
end
101
+ return JacFunctionWrapper {iip, oop, 3, F, typeof(fu), typeof(p), typeof(t)} (f,
102
+ fu, p, t)
103
+ else
104
+ throw (ArgumentError (""" Couldn't determine the function signature of `f` to
105
+ construct a JacobianWrapper!""" ))
65
106
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)
71
107
end
0 commit comments