This vignette outlines errors that might be generated when parsing odin code, with more explanation about the error and how they can be avoided. Don’t read this top to bottom as it’s quite boring! However, if we get errors that benefit from more explanation about why they’ve been thrown then we’ll expand on the contents here and arrange for these to be linked from the thrown error directly.
The error numbers are arbitrary after the first digit. The first digit will correspond to different phases of the parsing:
-
E0xxx
- general errors -
E1xxx
- errors during parsing of individual expressions -
E2xxx
- errors when considering the system as a whole
When an error is thrown you will be directed here, for example:
odin2::odin({
initial(x) <- 1
update(x) <- 1
1 < 10
})
#> Error in `odin2::odin()`:
#> ! Unclassifiable expression
#> ℹ Expected an assignment (with '<-') or a relationship (with '~')
#> → Context:
#> 1 < 10
#> ℹ For more information, run `odin2::odin_error_explain("E1001")`
You can then print the explanation:
odin2::odin_error_explain("E1001")
#>
#> ── E1001 ───────────────────────────────────────────────────────────────────────
#> We were not able to classify an expression in your odin source code.
#>
#> Example:
#>
#> a + 1
#>
E0001
You have used a feature that is not yet implemented, but which is intended to be implemented. Try again later. Probably the code you have written works well in odin v1.x.x but has not been implemented in odin2.
In some cases, code that produces this error may in future produce a different error code, if implementation is forecast to take a while.
E1002
Invalid assignment of data()
. If you use
data()
on the right hand side of an expression, then the
left hand side must be a symbol.
Example:
initial(x) <- data()
E1003
Invalid input to a special lhs function (initial()
,
update()
, etc). These functions all (currently) accept a
single unnamed argument.
Examples:
initial() <- 1
initial(a, b) <- 1
initial(x = a) <- 1
E1005
Invalid target on lhs of assignment.
Examples:
1 <- 10
The code above is valid R (as in, it can be parsed) but it is
nonsensical. At present the lhs of an assignment must be a symbol (e.g.,
a <- 1
). In future versions we will support assignments
into arrays (e.g., a[] <- 1
) but this is not yet
implemented.
This code is also reported if you have a spelling mistake, such as
inital() <- 1
instead of initial()
. It is also reported with this
code, which contains two legacy errors.
compare(d) <- Normal(0, 1)
Firstly, there is an error you may have made in the previous version,
in which the assignment <-
should be the comparison
symbol ~
. Furthermore, in this version, the
compare()
function is not required at all, and you should
write d ~ Normal(0, 1)
.
E1006
Invalid call to the parameter()
function, used on the
rhs of an assignment. If this error is thrown then we have failed to
parse the arguments of your call to parameter
. The full
prototype of parameter()
is:
parameter(default = NULL, constant = NULL, differentiate = FALSE)
We will fail to parse your call if:
- You provide more than three arguments
- You provide named arguments that do not match the three above
(
default
,constant
ordifferentiate
)
Example:
x <- parameter(value = 10)
This fails because value
is not a valid keyword argument
to parameter
.
E1007
Invalid default
argument to
parameter()
.
Currently we support very little of odin’s syntax within the default argument definition, though in future we may support more. It’s complicated (and a bit confusing) to allow use of other variables here because we end up with another copy of the dependency graph to consider (we have to be able to resolve all the possible relationships between quantities used as defaults before any of these quantities are used). It’s not impossible to support this and in future we may consider doing so.
At present, you may perform arithmetic operations on literal numbers. This allows you to write:
a <- parameter(1 / 3)
defining a
to be a parameter with a default value of
0.33333...
without having to write out a long floating
point number.
E1008
Invalid differentiate
argument to
parameter()
. You have provided something other than a
literal TRUE
or FALSE
here (e.g., a missing
value, an expression or a symbol).
E1009
Invalid constant
argument to parameter()
.
You have provided something other than a literal NULL
,
TRUE
or FALSE
here (e.g., a missing value, an
expression or a symbol).
E1010
Invalid call to data()
used on the right hand side.
Currently this function takes no arguments, though later we will expand
this to allow description of the data that you wish to use.
Example
d <- data(integer = TRUE)
Here, you have somewhat hopefully requested that d
will
be data as an integer but we don’t yet support that. Probably this will
be supported in future, but the interface is not yet decided. For now
all data elements are assumed to be scalar reals.
E1012
Invalid argument on the lhs of a ~
comparison.
Example
x / 2 ~ Normal(0, 1)
1 ~ Normal(0, 1)
The lhs of a ~
comparison must be a symbol. We may
expand this in the future to support arrays too.
E1013
Failed to parse the rhs of ~
as a valid distribution.
This can fail for many reasons, and the details of the failure come from
monty::monty_dsl_parse_distribution
Example reasons for failure include the the rhs being:
- not a call (e.g.,
x ~ 1
- not a call to distribution function (e.g.,
x ~ sqrt(2)
) - an invalid call (e.g.,
x ~ Normal(0, 1, 2)
)
The details for the failure will be included in the body of the error message.
E1014
Invalid assignment of parameter()
. If you use
parameter()
on the right hand side of an expression, then
the left hand side must be a symbol.
Example:
initial(x) <- parameter()
E1015
Differentiable parameters must not be constant. You have written
a <- parameter(constant = TRUE, differentiate = TRUE)
which is impossible. Parameters that are differentiable need to be
able to be set by dust::dust_system_update_pars()
as well
as on model creation.
Probably you want to set at least one of these to FALSE
,
or omit the argument and accept the default.
E1016
Failed to translate a user()
expression (valid in odin
before version 2) into a call to parameter()
. This was
likely code that would not work in old odin either.
E1017
Compatibility issues were present in the system (e.g., using
user()
instead of parameter()
and the
compatibility action was "error"
. You can, in the short
term, disable failure here by using
compatibility = "warning"
or
compatibility = "silent"
, but eventually this will become
an error that is always thrown when running with old odin code.
The error message will explain how to update your code to use new odin2 syntax.
E1018
Failed to parse a call to a stochastic function (e.g.,
Normal()
). These errors come from
monty::monty_dsl_parse_distribution
, typically where the
function call does not match arguments for any candidate call (some
distributions have multiple candidates, distinguished by argument
names).
Example calls that will fail:
* `Normal(1, 2, 3)` -- too many arguments
* `Normal()` -- too few arguments
* `Normal(mu = 0, sd = 1)` -- invalid argument names
The details for the failure will be included in the body of the error message.
E1019
Invalid value for the zero_every
argument to
initial()
. At present, this must be a literal value, and
that value must be an integer-like number (e.g., 2 or 2L). We may relax
this in future to allow more flexibility (e.g., a variable which
contains an integer-like number).
Examples that would error
initial(x, zero_every = a) <- 0
initial(y, zero_every = 2.5) <- 0
E1020
The right hand side of a call to initial()
that uses the
zero_every
argument was not 0, but it must be. Because we
periodically reset values to zero, any initial condition other than zero
makes no sense. See the
dust2
docs on periodic variables for details.
Examples that would error
initial(x, zero_every = 1) <- 10
initial(x, zero_every = 1) <- a
E1021
Invalid use of a special array access variable (e.g., i
,
j
, k
) on the right hand side of an expression.
The available index variables are determined by the rank (number of
dimensions) of the variable on the left hand side. If you have a vector
you can only use i
on the right hand side, if you have a
matrix you can use i
and j
and so on.
Example causing an error:
x[, ] <- a[i, k] + a[i, j]
Above, we have used k
on the rhs, but x
is
only a matrix so this would not work. Think of the above statement as it
might appear in generated pseudo-code:
for i in 1:nrow(x):
for j in 1:ncol(x):
x[i, j] <- a[i, k] + a[i, j]
and the reason that this is an error should be apparent.
E1022
Invalid use of :
within the left hand side of an array
assignment. We might increase the number of ways you can use this but
for now we are quite strict (the same rules as with version 1 of odin).
If you use :
it must be the outermost operator
within an index, so this is fine:
x[a:b]
but this is not
x[a:b + 1]
This is because we can’t generally convert the latter type into a
from:to
form, which we need for the code generation to
work, and also because R’s parsing rules are fairly ambiguous about if
this really means (a:b) + 1
or a:(b + 1)`.
E1023
Invalid functions used within an array index. At the moment you can
only use :
(the range operator, which must be the outermost
function call), +
, -
and (
. The
error will indicate the function that you have tried to use, and if you
feel this is unreasonable please let us know. We may expand the list of
supported functions within arrays in future, with candidates being
*
, %/%
and %%
.
E1024
Unary minus (-
as “negative” rather than “minus”)
detected within arrays. This error is a special case of E1023
but deserves special mention here
because it has special meaning in R’s array access. In R, we can
write
x[-1]
and this means “all of x
except the first element”,
which is something we might support in future.
E1025
Invalid use of i
, j
, etc on the left hand
side of an expression, for example:
x[i] <- 2 * a[i]
Usually, this error can be fixed by omitting the i
from
the left hand side as you probably meant
x[] <- 2 * a[i]
E1026
Something unexpected was used as an array index on the left hand side of an array expression, such as:
x[TRUE] <- 1
E1027
You have tried to use a function that odin does not support.
Example:
a <- pgamma(0, 1)
It’s also possible that you have simply misspelt the function you intended:
a <- sqt(2)
Not all of R’s mathematical functions are supported, but please let us know if you need something that we don’t support.
E1028
Invalid call to an odin function. Usually, this means that you have
provided too many or too few arguments, or that you have provided a
named argument that the function does not support. The message should
guide you to fix the mistake, but the machinery for doing this
(currently) comes from match.call
which can be unhelpful at
times.
Example:
a <- round(b, 2)
We don’t yet support round
’s digit
argument, so this call will fail.
E1029
Disallowed use of named arguments. For some primitive R functions
(e.g., +
we disallow use of named argument forms). You are
unlikely to see this error, but we would be interested to know if you
do.
E1030
Incorrect number of arguments to a function that does not accept argument names. You are unlikely to see this error, but we would be interested to know if you do.
E1031
Invalid type
argument to parameter()
. You
have provided something other than a literal "real"
,
"integer"
or "logical"
(e.g., a missing value,
an expression, symbol, or other string).
E1032
Impossible attempt to differentiate parameter with non-real type. You cannot differentiate integer or logical parameters. Example:
a <- parameter(type = "integer", differentiate = TRUE)
Here, you must decide if a
should be differentiable (in
which case remove the type
argument) or an integer (in
which case remove the differentiate
argument).
E1033
The argument to sum must be an array. This can either be a complete array (in which case the argument will be a symbol), or an indexed array. So these are both fine:
with the first summing over the whole array and the second summing
over rows (each element of b
will contain a sum over the
corresponding row of x
.
But these are errors:
Because summation is associative (or commutative) in this case we could write:
but in more complicated cases you may have to jump through more hoops to get the expression you want, and this may involve saving out an intermediate variable. For example, rather than writing:
a <- sum(x^2)
You might write:
xx[] <- x[i]^2
a <- sum(xx)
E1034
Invalid use of :
within a partial sum. If you use
:
it must be the outermost operator within an
index, so this is fine:
sum(x[a:b])
but this is not
sum(x[a:b + 1])
See E1022 for more information in the case where this same class of error is applied to indexing the left hand side of an assignment.
E2001
Your system of equations does not include any expressions with
initial()
on the lhs. This is what we derive the set of
variables from, so at least one must be present.
E2002
No call to deriv()
or update()
on the lhs
of any equation. Every call to initial()
requires a call to
deriv()
or update()
, and when there is not
even a single call to either of these we can’t tell what sort of time
your model runs in (i.e., if it works in continuous or discrete time).
This error is related to E2004
, but separate because we
can’t describe what is missing properly.
E2003
Variables are missing initial conditions.
All variables used in deriv()
or update()
require a corresponding entry in initial()
to set their
initial conditions. The error will highlight all lines that have a
deriv()
or update()
call that lacks a call to
initial()
. This can sometimes be because you have a
spelling error in your call to initial()
.
E2004
Variables are missing calls to deriv()
or
update()
You have a system where you use different equations for
deriv()
/update()
to the variables defined in
initial()
. This is an error if there are equations in
deriv()
/update()
that don’t have a
corresponding equation using initial()
, or if you have
equations in initial()
that don’t have a corresponding
deriv()
or update()
equation. The error will
highlight all lines that might be involved in the error.
E2005
Cyclic dependency detected within equations. There are a few ways this can happen. The simplest is that your equation references itself, for example:
a <- a + 1
Unlike in R, this is disallowed, as each variable may only be assigned to once within the target function of your system. Each assignment is much more like mathematical equation than usual programming statements.
You can get more complicated cycles, for example:
a <- c / 2
b <- sqrt(a)
c <- a + 1
Here a
depends on c
, c
depends
on b
and b
depends on a
. The
error will reference all the variables involved in cycle.
It is possible that there is more than one cycle within the reported expressions.
E2006
Undefined variable used in an equation. This error means that you have referenced some variable that does not exist within the odin system. Common reasons for this error include:
- A spelling mistake: you’ve referenced a variable that is very similar to the one that you meant to (we may add “did you mean support” in future; let us know if this would have saved you time).
- Trying to reference variables defined in R’s environment but not in odin. This is impossible, but you might want to make a parameter, perhaps.
Example:
This will error because v
(referenced by r
,
which is referenced by update(a)
) is undefined.
E2007
Trying to use dt
in a continuous time (ODE) system. This
is really a special case of E2006
, but we treat it
separately because it usually means that something has gone badly with
the system design.
E2008
An expression assigning as an array did not have a corresponding call
to dim()
. We always need this, even if it looks like we
should be able to work out how long your array is. You probably just
need to add a call like
dim(x) <- ...
for the variables mentioned in the error, with the appropriate lengths.
E2009
You have tried to assign to an array variable (i.e., something with a
dim()
call) without using []
on the left hand
side.
Example:
dim(a) <- 5
a <- 0
If you wanted a length-5 array of zeros here, you should write
a[] <- 0
E2010
Can’t reference data outside of equations that compare to data. You
have tried to reference some data (a variable that exists on the lhs of
a call to data()
) from an equation that is used anywhere
other than a comparison expression (involving ~
, or a
dependency of these equations). You cannot do this, because data do not
exist at this point.
Here’s a trivial example that would error:
Here, d
defines some data, and we try to use it from
update()
but we just can’t do that.