@@ -39,9 +39,13 @@ SymbolicUtils.isbinop(::Shift) = false
3939
4040function (D:: Shift )(x, allow_zero = false )
4141 ! allow_zero && D. steps == 0 && return x
42- Term {symtype(x)} (D, Any[x])
42+ if Symbolics. isarraysymbolic (x)
43+ Symbolics. array_term (D, x)
44+ else
45+ term (D, x)
46+ end
4347end
44- function (D:: Shift )(x:: Num , allow_zero = false )
48+ function (D:: Shift )(x:: Union{ Num, Symbolics.Arr} , allow_zero = false )
4549 ! allow_zero && D. steps == 0 && return x
4650 vt = value (x)
4751 if iscall (vt)
@@ -52,11 +56,11 @@ function (D::Shift)(x::Num, allow_zero = false)
5256 if D. t === nothing || isequal (D. t, op. t)
5357 arg = arguments (vt)[1 ]
5458 newsteps = D. steps + op. steps
55- return Num (newsteps == 0 ? arg : Shift (D. t, newsteps)(arg))
59+ return wrap (newsteps == 0 ? arg : Shift (D. t, newsteps)(arg))
5660 end
5761 end
5862 end
59- Num (D (vt, allow_zero))
63+ wrap (D (vt, allow_zero))
6064end
6165SymbolicUtils. promote_symtype (:: Shift , t) = t
6266
@@ -202,11 +206,19 @@ function (xn::Num)(k::ShiftIndex)
202206 x = value (xn)
203207 # Verify that the independent variables of k and x match and that the expression doesn't have multiple variables
204208 vars = Symbolics. get_variables (x)
205- length (vars) == 1 ||
209+ if length (vars) != 1
206210 error (" Cannot shift a multivariate expression $x . Either create a new unknown and shift this, or shift the individual variables in the expression." )
207- args = Symbolics. arguments (vars[]) # args should be one element vector with the t in x(t)
208- length (args) == 1 ||
211+ end
212+ var = only (vars)
213+ if ! iscall (var)
214+ throw (ArgumentError (" Cannot shift time-independent variable $var " ))
215+ end
216+ if operation (var) == getindex
217+ var = first (arguments (var))
218+ end
219+ if length (arguments (var)) != 1
209220 error (" Cannot shift an expression with multiple independent variables $x ." )
221+ end
210222
211223 # d, _ = propagate_time_domain(xn)
212224 # if d != clock # this is only required if the variable has another clock
@@ -220,6 +232,34 @@ function (xn::Num)(k::ShiftIndex)
220232 Shift (t, steps)(xn) # a shift of k steps
221233end
222234
235+ function (xn:: Symbolics.Arr )(k:: ShiftIndex )
236+ @unpack clock, steps = k
237+ x = value (xn)
238+ # Verify that the independent variables of k and x match and that the expression doesn't have multiple variables
239+ vars = ModelingToolkit. vars (x)
240+ if length (vars) != 1
241+ error (" Cannot shift a multivariate expression $x . Either create a new unknown and shift this, or shift the individual variables in the expression." )
242+ end
243+ var = only (vars)
244+ if ! iscall (var)
245+ throw (ArgumentError (" Cannot shift time-independent variable $var " ))
246+ end
247+ if length (arguments (var)) != 1
248+ error (" Cannot shift an expression with multiple independent variables $x ." )
249+ end
250+
251+ # d, _ = propagate_time_domain(xn)
252+ # if d != clock # this is only required if the variable has another clock
253+ # xn = Sample(t, clock)(xn)
254+ # end
255+ # QUESTION: should we return a variable with time domain set to k.clock?
256+ xn = wrap (setmetadata (unwrap (xn), VariableTimeDomain, k. clock))
257+ if steps == 0
258+ return xn # x(k) needs no shift operator if the step of k is 0
259+ end
260+ Shift (t, steps)(xn) # a shift of k steps
261+ end
262+
223263Base.:+ (k:: ShiftIndex , i:: Int ) = ShiftIndex (k. clock, k. steps + i)
224264Base.:- (k:: ShiftIndex , i:: Int ) = k + (- i)
225265
0 commit comments