odin icon indicating copy to clipboard operation
odin copied to clipboard

off-by-one in discrete delay with delay in C

Open richfitz opened this issue 5 years ago • 1 comments

I think we need to push the initial conditions onto the ring

richfitz avatar Mar 15 '19 16:03 richfitz

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)
+  }
 }

richfitz avatar Mar 15 '19 16:03 richfitz