odin
odin copied to clipboard
off-by-one in discrete delay with delay in C
I think we need to push the initial conditions onto the ring
diff --git a/R/generate_c_equation.R b/R/generate_c_equation.R
index 43a77e0..839e609 100644
--- a/R/generate_c_equation.R
+++ b/R/generate_c_equation.R
@@ -369,9 +369,7 @@ generate_c_equation_delay_continuous <- function(eq, data_info, dat, rewrite) {
generate_c_equation_delay_discrete <- function(eq, data_info, dat, rewrite) {
- if (!is.null(eq$delay$default)) {
- stop("Discrete delays with default not yet supported [odin bug]")
- }
+ has_default <- !is.null(eq$delay$default)
## This can't currently be false I believe:
stopifnot(data_info$storage_type == "double")
@@ -408,18 +406,37 @@ generate_c_equation_delay_discrete <- function(eq, data_info, dat, rewrite) {
if (data_info$rank == 0L) {
## always transient, so needs declaration:
- assign <- sprintf("double %s = %s[0];", lhs, tail)
+ fmt <- "%s = %s[0];"
+ if (!has_default) {
+ fmt <- paste("double", fmt)
+ }
+ assign <- sprintf(fmt, lhs, tail)
} else {
assign <- sprintf("memcpy(%s, %s, %s * sizeof(double));",
lhs, tail, rewrite(data_info$dimnames$length))
}
- c(get_ring_head,
- push,
- advance,
- sprintf_safe("double * %s;", tail),
- c_expr_if(time_check, data_initial, data_offset),
- assign) -> ret
+ declare_tail <- sprintf_safe("double * %s;", tail)
+
+ if (has_default) {
+ if (data_info$rank == 0) {
+ set_default <- sprintf("%s = %s;", lhs, rewrite(eq$delay$default))
+ } else {
+ stop("Fixme")
+ }
+ c(get_ring_head,
+ push,
+ advance,
+ sprintf("double %s;", lhs),
+ c_expr_if(time_check, set_default, c(declare_tail, data_offset, assign)))
+ } else {
+ c(get_ring_head,
+ push,
+ advance,
+ declare_tail,
+ c_expr_if(time_check, data_initial, data_offset),
+ assign)
+ }
}