--- title: "Odin parse errors" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Odin parse errors} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` 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: ```{r error = TRUE} odin2::odin({ initial(x) <- 1 update(x) <- 1 1 < 10 }) ``` You can then print the explanation: ```{r} odin2::odin_error_explain("E1001") ``` # `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. # `E1001` We were not able to classify an expression in your odin source code. Example: ``` a + 1 ``` # `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 ``` # `E1004` Assignment to reserved words (in odin, C, C++ or JavaScript) is not allowed. An example statement that would trigger this: ``` new <- 2 * old ``` This is an error because [`new` is a keyword in C++](https://en.cppreference.com/w/cpp/language/new). The list of forbidden keywords can be found in `vignette("functions"`) (Section: "Restricted names"). # `E1005` Invalid target on lhs of assignment. There are quite a few ways of being an invalid assignment target, and at present they are all grouped within this error. We may split these into different errors in future where particular types of error are both common and difficult to understand. Examples: ``` 1 <- 10 ``` The code above is valid R (as in, it can be parsed) but it is nonsensical. Generally, the lhs of an assignment must be a symbol (e.g., `a <- 1`). This code is also reported if you have a spelling mistake, such as ``` inital(x) <- 1 ``` instead of `initial(x)`, though we will try and suggest the appropriate function if you have a near miss. 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)`. If you assign into an array, then the array name must be a symbol, so this is invalid: ``` f(x)[] <- 1 ``` as is this: ``` deriv(1[]) <- 1 ``` Sometimes you will see this error if you have accidentally nested special functions ``` deriv(deriv(x)) <- 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` or `differentiate`) 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](https://mrc-ide.github.io/dust2/articles/periodic.html) 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: ```r 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: ```r x[a:b] ``` but this is not ```r 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`](#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: ```r x[i] <- 2 * a[i] ``` Usually, this error can be fixed by omitting the `i` from the left hand side as you probably meant ```r x[] <- 2 * a[i] ``` # `E1026` Something unexpected was used as an array index on the left hand side of an array expression, such as: ```r x[TRUE] <- 1 ``` # `E1027` You have tried to use a function that odin does not support. Example: ```r a <- pgamma(0, 1) ``` It's also possible that you have simply misspelt the function you intended: ```r 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: ```r 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: ```r 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: ```r a <- sum(x) b[] <- sum(x[, i]) ``` 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: ```r a <- sum(a + y) b[] <- sum([, i] + 1) ``` Because summation is associative (or commutative) in this case we could write: ```r a <- sum(a) + sum(y) b[] <- sum([, i]) + 1 ``` 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: ```r a <- sum(x^2) ``` You might write: ```r 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: ```r sum(x[a:b]) ``` but this is not ```r sum(x[a:b + 1]) ``` See [E1022](#e1022) for more information in the case where this same class of error is applied to indexing the left hand side of an assignment. # `E1035` Invalid arguments to interpolation. The first two arguments (`time` and `value`, respectively) must be symbols corresponding to arrays. The whole array is used by `interpolate()` so these cannot be subset. # `E1036` Invalid interpolation mode. The `mode` argument to `interpolate` must be a string, and must be one of the values `"constant"` (for piecewise constant), `"linear"` (for piecewise linear) or `"spline"` (for cubic splines). Example: ```r a <- interpolate(at, ay, "wiggly") ``` # `E1037` Calls to interpolate must be assigned to a symbol, because they affect the **whole** structure. This is academic until we support interpolation of several series at the same time, but rather than writing: ``` a[] <- interpolate(at, ay, "linear") dim(a) <- 10 ``` we expect to see ``` a <- interpolate(a, y, "linear") dim(a) <- 10 ``` This is similar to the requirement that array-valued parameters are assigned at once (in contrast to odin version 1). # `E1038` This equation cannot reference itself. There are some types of equations that **can** reference themselves, for example: ``` update(x) <- x + 1 # references 'x' from the previous step deriv(x) <- x # derivative referencing the actual variable x[2:n] <- x[i] / x[i - 1] # referencing elsewhere in the array ``` However, in general this makes little sense and is disallowed, for example: ``` b <- b + 1 ``` This is not allowed because we have a cycle in the graph for `b` (a special case of [E2005](#e2005)). # `E1039` Array extent cannot be stochastic. This is really a special case of [E2011](#e2011) but detectable in a single expression. An example that would throw this error is: ``` dim(a) <- Poisson(2) ``` # `E1040` Array extent cannot be determined by time. This is really a special case of [E2011](#e2011) but detectable in a single expression. An example that would throw this error is: ``` dim(a) <- if (time > 10) 100 else 20 ``` # `E1041` Special functions on the right-hand-side of an expression must be the only expression there. This applies to `parameter()`, `interpolate()` and `data()`; if these are used they must be the **only** expression on the right hand side. For example you cannot write: ``` x <- interpolate(at, ay) + interpolate(bt, by) ``` You might write this as: ``` a <- interpolate(at, ay) b <- interpolate(bt, by) x <- a + b ``` # `E1042` Invalid special function used on the right hand side. Some odin functions can only be used on the lhs; these include `initial`, `update` and `deriv`. So you cannot write this: ``` a <- x + deriv(y) ``` # `E1043` Invalid functions used in expression for `dim()`. Currently `dim()` is quite limited in what it can accept (though slightly more relaxed than `odin1`). You can use `+`, `-`, `(`, `length`, `nrow` and `ncol` but nothing else. Let us know if you think you should be able to use more. # `E1044` Attempt to call something which is not the **name** of a function. This might be ``` a <- 1(x) ``` where `1` is not a symbol, so this fails. Other possible errors, which are valid R code but not valid odin code, might include: ``` a <- f(x)(y) ``` where `f(x)` might return a function in R, but this is not possible in odin. # `E1045` Attempt to use one of R's reserved words: `function`, `while`, `repeat`, `for`, etc. # `E1046` All `if` statements must have an `else` clause. You cannot write: ``` a <- if (condition) 1 ``` as this is really the same as (in R) ``` a <- if (condition) 1 else NULL ``` which would not be valid in odin because we can't assign a `NULL` value. Always provide an `else` branch. # `E1047` Assignment to a name that starts with a restricted prefix. Names cannot begin with `odin_`, `interpolate_`, `delay_` or `adjoint_`. An example that would trigger this: ``` delay_cases_days <- 10 ``` # `E1048` Cannot assign to `time`. Prior to odin2, this was allowed as `t` was the name for time in continuous-time models and discrete time models sometimes wrote: ``` time <- step * dt ``` We can migrate the above special case, but any other assignments to `time` are disallowed, and you will need to update your model. See `vignette("migrating")` for more information. # `E1049` Cannot assign to `dt`. Prior to odin2, this was how `dt` was controlled, but now you should control `dt` via `dust2::dust_system_create` and `dust2::dust_filter_create` etc. Previously you might have written ``` dt <- parameter(0.5) # or really user() in old odin code ``` but this is no longer allowed. We can migrate this special case, but other uses such as ``` dt <- 0.5 ``` are disallowed and you will need to update your model. See `vignette("migrating")` for more information. # `E1050` Cannot use `step` within discrete time models. Prior to odin version 2, the `step` variable was automatically provided by odin to be the time basis for discrete time models; models started at step 0 and increased by one each time step. We no longer support this, and instead models start at some real-valued (but integral) time and increment with a step size of `dt` (which must be of the form `1 / `). You will need to adapt your code to fix this error, and this may require features that we are still developing. Please see `vignette("migrating")` for details. # `E1051` Array parameters cannot have defaults. If `a` is an array (of any rank), then this is an error: ```r a <- parameter(1) ``` In future, we may allow this to allow filling an array with a value on initialisation. However, if we did this we'd also like to support something like ```r a <- parameter(c(1, 2, 3)) ``` to have a default value of vector of 1:3; however this is quite hard to validate and generalises poorly to higher dimensions. Your thoughts and use-cases are very welcome. # `E1052` Failed to parse call to `print()`. If this error is thrown then we have failed to parse the arguments of your call to `print`. The full prototype of `print()` is: ``` print(string, when = NULL) ``` We will fail to parse your call if: * You provide more than two arguments * You provide named arguments that do not match the two above (`string`, `when`) # `E1053` Invalid first (`string`) argument to `print()`. This argument must be a string, it must be parseable by `glue::glue()` using curly-brace delimiters, and it must contain at least one template argument. If you see this error, it's likely you have failed to terminate a template, such as: ``` print("v: {value") ``` Here, we might have meant to write `"v: {value}"` (note the closing `}`), but because we did not terminate the template, `glue` failed to parse the string. # `E1054` Failed to parse template within print string. Unlike [E1053](#e1053) this is an error **within** a template. Typically this will be one of two issues: * The expression within `{}` is not valid R * The format specifier after `;` is not interpretable (see `vignette("debugging")` for details) Examples ``` print("x: {x + }") # invalid as `x +` is an incomplete expression print("x: {x; q}") # invalid as `q` is not an sprintf format ``` # `E1055` Invalid use of `rank` argument to `parameter()` call that does not assign to dimensions. You might have written ``` a <- parameter(rank = 2) ``` but this is not the place to include the `rank` argument. Instead, it should go onto the call with `dim(a)` on the left-hand-side. # `E1056` Missing `rank` argument to call to `parameter()` which assigns to `dim()`. You may have written ``` dim(a) <- parameter() ``` but here we need to know what rank `a` is (is it a vector, matrix, etc). You can fix this by writing ``` dim(a) <- parameter(rank = 2) ``` with the value of the `rank` argument being a literal integer. See `vignette("functions")` for more information on this interface. # `E1057` Invalid value for `rank` argument to `parameter()`. Where given it must be a positive size; literally an integer value of 1, 2, 3, ..., 8. You cannot use a variable here. # `E1058` Failed to migrate expression of form ```r dim(a) <- user() ``` because we never found an assignment like ``` a[] <- user() ``` where we could determine the rank. This might be because you've removed the square brackets from the original, or the original assignment is simply missing. If your code does compile with odin1 but you see this error code please let us know. # `E1059` Failed to parse call to `browser()`. Note that while this shares ideas and a core implementation with R's `browser()`, the call in odin code is different and must have the form ```r browser(phase, when) ``` where `phase` is the phase to evaluate the browser (one of `update` or `deriv` for now) and `when` is an expression describing the conditions to evaluate the `browser` call. # `E1060` Invalid `phase` argument for call to `browser()`. Currently this must be one of `update` or `deriv`, but we may expand this in future. # `E1061` You can use the built-in constant `pi` on the right hand side of an expression, without setting it. You should not use it on the left-hand side of any expression. # `E1062` Cannot use missing values (`NA`) within expressions. Handling of missing values in C++ code is complicated, particularly following the semantics that R uses, with missing values for integers and logicals, and sensible propagation of missingness through expressions. In most systems a missing value will propagate though the whole system very quickly and we don't expect this is very useful. Example code that would throw this error: ```r a <- NA ``` # `E1063` Trying to use the arguments `min` or `max` in a `parameter()` call defining a logical parameter. This is not supported because logical parameters can only take the values `TRUE` and `FALSE`. Example code that would throw this error: ```r a <- parameter(type = "logical", min = 0) ``` # `E1064` Invalid argument for `min` or `max` in a `parameter()` call. You can only use numbers here, not expressions or symbols. We may relax this in future, so please let us know if this is a problem. Example assignments that would throw this error: ```r a <- parameter(min = 1/2) # 1/2 is really an expression, use 0.5 instead b <- parameter(max = a) # would create dependency issues c <- parameter(min = TRUE) # not a number d <- parameter(max = NaN) # also not a number! ``` # `E1065` Impossible range implied by `min` and `max` in `parameter()` call. This is thrown when `min` is greater than or equal to `max` as either this means you really have a constant, or no value can satisfy the relationship. Example assignment that would throw this error ``` a <- parameter(min = 10, max = 0) ``` # `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: ```r 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: ```r 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: ```r initial(a) <- 1 update(a) <- a * r r <- exp(v) ``` 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 ```r 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: ```r 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: ```r initial(x) <- 1 update(x) <- x + d d <- data() ``` Here, `d` defines some data, and we try to use it from `update()` but we just can't do that. # `E2011` Array extents must be determined at system creation. This means that they cannot be changed when setting parameters into the model, or by time. An example that would throw this error: ``` dim(a) <- n n <- parameter(type = "integer") ``` Here, parameter is not constant (it can be updated); you can fix this by writing this as: ``` dim(a) <- n n <- parameter(type = "integer", constant = TRUE) ``` Similarly, if `n` depended on `time`, or if it was (or depended on) anything stochastic, this would be an error because then the array dimension would have to change every time step. # `E2012` Assignments to the same variable must all be to arrays. You cannot write, for example: ``` a <- 1 + 2 a <- sqrt(a) ``` to compute `a` in two stages. Sometimes this error will be thrown because you have been inconsistent with use of array-assignment square brackets, for example: ``` a <- 0 a[2] <- 1 ``` Above, the first line probably should have been `a[] <- 0 or `a[1] <- 0`. # `E2013` Multiline array equations must be written as consecutive statements, with no assignments to other variables in between (comments are fine). So this is an error: ``` a[1] <- 1 b <- 10 a[2] <- b ``` Because the assignment to `b` occurs within the block of assignments to `a[]`. When we evaluate the expressions, all of the assignments to `a` will happen in one go (in the order written) and if you interleave them it gives the false idea of controlling the flow of equations more than you really can. # `E2014` An equation has a name that shadows a variable. You may have written something like: ``` initial(a) <- 1 update(a) <- a + 1 a <- 2 ``` which is invalid because `a` is both an ordinary equation and also part of the system state. # `E2015` Invalid rank inputs to `interpolate()`. The time input (first argument) must always be a vector (rank 1), being a sequence of times corresponding to the times of inputs to interpolate. The value input (second argument) will have rank **one greater** than the output. So: * if the output is a scalar, then the value must be a vector * if the output is a vector, the value must be a matrix * if the output is a matrix, the value must be a 3-dimensional array and so on. This error is thrown where your inputs do not satisfy these tests. # `E2016` Your system contains unused equations. This is currently always an error (in odin1 this could be converted to a warning, message or ignored), and we may allow downgrading this error in a future version. Code that would generate this error: ``` update(x) <- x + 1 initial(x) <- x a <- 1 ``` Here, `a` is unused. Perhaps it was meant to be an initial condition, or the amount that `x` is incremented, but at present it does nothing. # `E2017` Attempt to browse a phase that does not exist. You have a call like ``` browser("update") ``` in a system of ODEs which does not have an update phase. The error will indicate which phases are valid. # `E2018` Array rank in expression differs from the rank declared with `dim` Here, the number of dimensions for a variable in an expression is different from the number declared with the `dim` function, which is the source of truth for rank. For example, you might declare a matrix and a 3-dimensional structure like this:- ``` dim(xy) <- c(5,5) dim(xyz) <- parameter(rank = 3) ``` When you use these in other expressions, the rank must match the declaration above. So these examples would be valid syntax:- ``` initial(xy[, ]) <- 0 xyz[1, 2, 3] <- 5 xy <- sum(xyz[1, ,]) ``` but these would not:- ``` update(xy[]) <- 1 xyz[1, 2] <- xyz[1, 2] + 1 ``` # `E2019` The `length`, `ncol` and `nrow` functions take as their argument a whole array, matrix, or higher-order structure, without brackets or indexing. So ``` dim(x) <- c(5,5) y <- length(x) ``` is valid, but ``` y <- length(x[, 1] y <- length(x[]) ``` are both invalid. # `E2020` `output()` was used (on lhs) within a discrete-time system. You can only use `output()` within systems that involve `deriv()` as it provides a way of computing variables for which you do not have derivatives. If you are writing a discrete-time system, you should use `update()` with a corresponding `initial()` statement.