Skip to content

Commit cb8ea9f

Browse files
error when no derivative
1 parent 5b88e12 commit cb8ea9f

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,49 @@ opts = Dict{Symbol,Bool}(
126126
and calls the function `ode_def_opts(name::Symbol,opts,ex::Expr,params)`. Note that
127127
params is an iterator holding expressions for the parameters.
128128

129+
#### Extra Little Tricks
130+
131+
There are some extra little tricks you can do. Since `@ode_def` is a macro,
132+
you cannot directly make the parameters something that requires a runtime value.
133+
Thus the following will error:
134+
135+
```julia
136+
vec = rand(1,4)
137+
f = @ode_def LotkaVolterraExample begin
138+
dx = ax - bxy
139+
dy = -cy + dxy
140+
end a=>vec[1] b=>vec[2] c=>vec[3] d=vec[4]
141+
```
142+
143+
To do the same thing, instead initialize it with values of the same type, and simply
144+
replace them:
145+
146+
```julia
147+
vec = rand(1,4)
148+
f = @ode_def LotkaVolterraExample begin
149+
dx = ax - bxy
150+
dy = -cy + dxy
151+
end a=>1.0 b=>1.0 c=>1.0 d=vec[4]
152+
f.a,f.b,f.c = vec[1:3]
153+
```
154+
155+
Notice that when using `=`, it can inline expressions. It can even inline expressions
156+
of time, like `d=3*t` or `d=2π`. However, do not use something like `d=3*x` as that will
157+
fail to transform the `x`.
158+
159+
In addition, one can also use their own function inside of the macro. For example:
160+
161+
```julia
162+
f(x,y,d) = erf(x*y/d)
163+
NJ = @ode_def FuncTest begin
164+
dx = a*x - b*x*y
165+
dy = -c*y + f(x,y,d)
166+
end a=>1.5 b=>1 c=3 d=4
167+
```
168+
169+
will do fine. The symbolic derivatives will not work unless you define a derivative
170+
for `f`.
171+
129172
#### Extra Macros
130173

131174
Instead of using `ode_def_opts` directly, one can use one of the following macros

src/ode_def_opts.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,14 @@ function ode_def_opts(name::Symbol,opts::Dict{Symbol,Bool},ex::Expr,params...;M=
108108

109109
# Build the Julia function
110110
Jex = build_jac_func(symjac,indvar_dict,param_dict,inline_dict)
111+
bad_derivative(Jex)
111112
jac_exists = true
112113

113114
if opts[:build_expjac]
114115
try
115116
expjac = expm*symjac) # This does not work, which is why disabled
116117
expJex = build_jac_func(expjac,indvar_dict,param_dict,inline_dict)
118+
bad_derivative(expJex)
117119
expjac_exists = true
118120
catch
119121
warn("Jacobian could not exponentiate")
@@ -124,6 +126,7 @@ function ode_def_opts(name::Symbol,opts::Dict{Symbol,Bool},ex::Expr,params...;M=
124126
try # Jacobian Inverse
125127
invjac = inv(symjac)
126128
invJex = build_jac_func(invjac,indvar_dict,param_dict,inline_dict)
129+
bad_derivative(invJex)
127130
invjac_exists = true
128131
catch err
129132
warn("Jacobian could not invert")
@@ -134,8 +137,10 @@ function ode_def_opts(name::Symbol,opts::Dict{Symbol,Bool},ex::Expr,params...;M=
134137
syminvW = inv(M - γ*symjac)
135138
syminvW_t = inv(M/γ - symjac)
136139
invWex = build_jac_func(syminvW,indvar_dict,param_dict,inline_dict)
140+
bad_derivative(invWex)
137141
invW_exists = true
138142
invWex_t = build_jac_func(syminvW_t,indvar_dict,param_dict,inline_dict)
143+
bad_derivative(invWex_t)
139144
invW_t_exists = true
140145
catch err
141146
warn("Rosenbrock-W could not invert")
@@ -149,11 +154,13 @@ function ode_def_opts(name::Symbol,opts::Dict{Symbol,Bool},ex::Expr,params...;M=
149154
end
150155
# Build the Julia function
151156
Hex = build_jac_func(symhes,indvar_dict,param_dict,inline_dict)
157+
bad_derivative(Hex)
152158
hes_exists = true
153159
if opts[:build_invhes]
154160
try # Hessian Inverse
155161
invhes = inv(symhes)
156162
invHex = build_jac_func(invhes,indvar_dict,param_dict,inline_dict)
163+
bad_derivative(invHex)
157164
invhes_exists = true
158165
catch err
159166
warn("Hessian could not invert")

src/ode_findrep.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ function ode_findreplace(ex,symex,indvar_dict,param_dict,inline_dict;params_from
2626
end
2727
end
2828

29+
function bad_derivative(ex)
30+
for (i,arg) in enumerate(ex.args)
31+
if isa(arg,Expr)
32+
bad_derivative(arg)
33+
elseif arg == :Derivative
34+
warn("Undefined derivative found. If you are using a non-elementary function, you must define the derivative in order to calculate Jacobians et. al. Please refer to the documentation.")
35+
error("Failed")
36+
end
37+
end
38+
end
39+
2940

3041

3142
function ode_symbol_findreplace(ex,indvar_dict,param_dict,inline_dict;params_from_function=true)

0 commit comments

Comments
 (0)