diff --git a/models/square_wave_oscillator.jl b/models/square_wave_oscillator.jl new file mode 100644 index 0000000000000000000000000000000000000000..e4bb08ef60c2f02d1dd530da6cb538008eaead35 --- /dev/null +++ b/models/square_wave_oscillator.jl @@ -0,0 +1,67 @@ + +d=3 +k=7 +dict_var_square = Dict(:A => 1, :HIGH => 2, :LOW => 3) +dict_params_square = Dict(:p1 => 1, :w1 => 2, :p2 => 3, :w2 => 4, :p3 => 5, :w3 => 6, :d => 7) +l_tr_square = [:Tu, :t1, :t2, :t3] +p_square = [1, 0, 0, 0, 0, 0, 5.0] +x0_square = [1, 0, 1] +t0_square = 0.0 +function square_wave_f!(xnplus1::Vector{Int}, l_t::Vector{Float64}, l_tr::Vector{Transition}, + xn::Vector{Int}, tn::Float64, p::Vector{Float64}) + if p[1] == 0 && p[3] == 0 && p[5] == 0 + copyto!(xnplus1, xn) + return nothing + end + # If in state LOW + if xn[3] == 1 + xnplus1[1] = 10 + xnplus1[2] = 1 + xnplus1[3] = 0 + l_t[1] += p[7] + l_tr[1] = :Tu + # If in state HIGH + else + possible_transitions = (:t1, :t2, :t3) + l_priority = (p[1], p[3], p[5]) + l_weights = (p[2], p[4], p[6]) + max_priority = maximum(l_priority) + l_idx = zeros(Int, 0) + for i = eachindex(l_priority) + if l_priority[i] >= max_priority + push!(l_idx, i) + end + end + if length(l_idx) == 1 + transition = l_idx[1] + else + wsum = sum(l_weights[l_idx]) + b_inf = 0.0 + b_sup = l_weights[l_idx[1]] + transition = 0 + u = rand() + for i in l_idx + if b_inf < wsum*u < b_sup + transition = i + break + end + @inbounds b_inf += l_weights[i] + @inbounds b_sup += l_weights[i] + end + end + xnplus1[1] = 1 + xnplus1[2] = 0 + xnplus1[3] = 1 + l_t[1] += 2^(transition-1) * p[7] + l_tr[1] = possible_transitions[transition] + end +end +isabsorbing_square_wave(p::Vector{Float64}, xn::Vector{Int}) = (p[1] == 0 && p[3] == 0 && p[5] == 0) +g_square_wave = [:A, :HIGH, :LOW] + +square_wave_oscillator = ContinuousTimeModel(d, k, dict_var_square, dict_params_square, l_tr_square, + p_square, x0_square, t0_square, square_wave_f!, isabsorbing_square_wave; + g=g_square_wave, name="square wave oscillator pkg", time_bound = 105.0) + +export square_wave_oscillator + diff --git a/tests/run_unit.jl b/tests/run_unit.jl index fe64702f8404c376b23ddb20eeefe89e25b5ab19..c3f168db93b90280cefe936be08179266e1da409 100644 --- a/tests/run_unit.jl +++ b/tests/run_unit.jl @@ -40,5 +40,6 @@ using Test @test include("unit/simulate_sir.jl") @test include("unit/simulate_sir_bounded.jl") @test include("unit/simulate_er.jl") + @test include("unit/square_wave_oscillator.jl") end diff --git a/tests/unit/square_wave_oscillator.jl b/tests/unit/square_wave_oscillator.jl new file mode 100644 index 0000000000000000000000000000000000000000..057b7fc1197496b0b2a178e31c0fb6810683543a --- /dev/null +++ b/tests/unit/square_wave_oscillator.jl @@ -0,0 +1,32 @@ + +using MarkovProcesses +load_model("square_wave_oscillator") +swo = square_wave_oscillator + +swo_reg1 = deepcopy(swo) +set_param!(swo_reg1, [:p1, :p2, :p3], [1.0, 0.0, 0.0]) + +swo_reg2 = deepcopy(swo) +set_param!(swo_reg2, [:p1, :p2, :p3], [0.0, 1.0, 0.0]) + +swo_reg3 = deepcopy(swo) +set_param!(swo_reg3, [:p1, :p2, :p3], [0.0, 0.0, 1.0]) + +swo_irreg1 = deepcopy(swo) +set_param!(swo_irreg1, [:p1, :p2, :p3], [1.0, 1.0, 0.0]) +set_param!(swo_irreg1, [:w1, :w2, :w3], [1.0, 1.0, 0.0]) + +swo_irreg2 = deepcopy(swo) +set_param!(swo_irreg2, [:p1, :p2, :p3], [0.0, 1.0, 1.0]) +set_param!(swo_irreg2, [:w1, :w2, :w3], [0.0, 1.0, 1.0]) + +swo_irreg3 = deepcopy(swo) +set_param!(swo_irreg3, [:p1, :p2, :p3], [1.0, 0.0, 1.0]) +set_param!(swo_irreg3, [:w1, :w2, :w3], [1.0, 0.0, 1.0]) + +swo_irreg4 = deepcopy(swo) +set_param!(swo_irreg4, [:p1, :p2, :p3], [1.0, 1.0, 1.0]) +set_param!(swo_irreg4, [:w1, :w2, :w3], [1.0, 1.0, 1.0]) + +return true +