Skip to content

Commit 4f1fe9b

Browse files
committed
add ClockChange operator
1 parent e1befe0 commit 4f1fe9b

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/discretedomain.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,29 @@ Returns true if the expression or equation `O` contains [`Hold`](@ref) terms.
147147
"""
148148
hashold(O) = recursive_hasoperator(Hold, unwrap(O))
149149

150+
# ClockChange
151+
152+
"""
153+
$(TYPEDEF)
154+
155+
Change the clock of a discrete-time variable by sub or super sampling
156+
```
157+
cont_x = ClockChange(from, to)(disc_x)
158+
```
159+
"""
160+
@kwdef struct ClockChange <: Operator
161+
from::Any
162+
to::Any
163+
end
164+
(D::ClockChange)(x) = Term{symtype(x)}(D, Any[x])
165+
(D::ClockChange)(x::Num) = Num(D(value(x)))
166+
SymbolicUtils.promote_symtype(::ClockChange, x) = x
167+
168+
function Base.:(==)(D1::ClockChange, D2::ClockChange)
169+
isequal(D1.to, D2.to) && isequal(D1.from, D2.from)
170+
end
171+
Base.hash(D::ClockChange, u::UInt) = hash(D.from, hash(D.to, xor(u, 0xa5b640d6d952f101)))
172+
150173
# ShiftIndex
151174

152175
"""
@@ -242,10 +265,14 @@ function input_timedomain(h::Hold, arg = nothing)
242265
end
243266
output_timedomain(::Hold, arg = nothing) = Continuous()
244267

268+
input_timedomain(cc::ClockChange, arg = nothing) = cc.from
269+
output_timedomain(cc::ClockChange, arg = nothing) = cc.to
270+
245271
sampletime(op::Sample, arg = nothing) = sampletime(op.clock)
246272
sampletime(op::ShiftIndex, arg = nothing) = sampletime(op.clock)
273+
sampletime(op::ClockChange, arg = nothing) = sampletime(op.to)
247274

248-
changes_domain(op) = isoperator(op, Union{Sample, Hold})
275+
changes_domain(op) = isoperator(op, Union{Sample, Hold, ClockChange})
249276

250277
function output_timedomain(x)
251278
if isoperator(x, Operator)

test/clock.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,24 @@ prob = ODEProblem(sys, [], (0.0, 10.0), [x(k - 1) => 2.0])
528528
int = init(prob, Tsit5(); kwargshandle = KeywordArgSilent)
529529
@test int.ps[x] == 3.0
530530
@test int.ps[x(k - 1)] == 2.0
531+
532+
## ClockChange
533+
using ModelingToolkit: D_nounits as D
534+
k1 = ShiftIndex(Clock(t, 1))
535+
k2 = ShiftIndex(Clock(t, 2))
536+
@mtkmodel CC begin
537+
@variables begin
538+
x(t) = 0
539+
y(t) = 0
540+
dummy(t) = 0
541+
end
542+
@equations begin
543+
x(k1) ~ x(k1 - 1) +
544+
ModelingToolkit.ClockChange(from = k2.clock, to = k1.clock)(y(k2))
545+
y(k2) ~ y(k2 - 1) + 1
546+
D(dummy) ~ 0
547+
end
548+
end
549+
@mtkbuild cc = CC()
550+
prob = ODEProblem(cc, [], (0, 10))
551+
sol = solve(prob, Tsit5(); kwargshandle = KeywordArgSilent)

0 commit comments

Comments
 (0)