Skip to content

time_forced_switch

Time-forced switching benchmark.

time_forced_switch(period=1.0, initial_state=None)

Create a system with periodic time-triggered switches.

A clock state is appended and reset at each transition to enforce a fixed dwell time in each location.

Parameters:

Name Type Description Default
period float

Switching period between locations.

1.0
initial_state ndarray | None

Optional initial [x1, x2] or [x1, x2, clock].

None

Returns:

Type Description
HybridSystem

HybridSystem with time-triggered switches.

Source code in src/flowcean/hybrid/benchmarks/time_forced_switch.py
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def time_forced_switch(
    period: float = 1.0,
    initial_state: np.ndarray | None = None,
) -> HybridSystem:
    """Create a system with periodic time-triggered switches.

    A clock state is appended and reset at each transition to enforce a fixed
    dwell time in each location.

    Args:
        period: Switching period between locations.
        initial_state: Optional initial [x1, x2] or [x1, x2, clock].

    Returns:
        HybridSystem with time-triggered switches.
    """

    def flow_fast(
        _t: float,
        state: np.ndarray,
        _params: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        x1, x2, clock = state
        return np.array([-2.0 * x1, -1.0 * x2, 1.0 + 0.0 * clock], dtype=float)

    def flow_slow(
        _t: float,
        state: np.ndarray,
        _params: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        x1, x2, clock = state
        return np.array([-0.5 * x1, -0.2 * x2, 1.0 + 0.0 * clock], dtype=float)

    def event_surface_dwell(
        _t: float,
        state: np.ndarray,
        params: Parameters,
        _input_stream: InputStream,
    ) -> float:
        return state[2] - params["dwell_time"]

    def reset_clock(
        _t: float,
        state: np.ndarray,
        _parameters: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        updated = state.copy()
        updated[2] = 0.0
        return updated

    fast_dynamics = ContinuousDynamics(flow_fast, label="fast")
    slow_dynamics = ContinuousDynamics(flow_slow, label="slow")
    fast = Location(fast_dynamics, label="fast")
    slow = Location(slow_dynamics, label="slow")
    event = EventSurface(
        event_surface_dwell,
        direction=CrossingDirection.RISING,
        label="dwell",
    )
    reset = Reset(reset_clock, label="reset_clock")

    to_slow = Transition(
        source=fast,
        target=slow,
        event=event,
        reset=reset,
    )
    to_fast = Transition(
        source=slow,
        target=fast,
        event=event,
        reset=reset,
    )

    if initial_state is None:
        initial_state = np.array([1.0, -1.0, 0.0], dtype=float)
    elif initial_state.shape[0] == STATE_DIM_NO_CLOCK:
        initial_state = np.array(
            [initial_state[0], initial_state[1], 0.0],
            dtype=float,
        )

    return HybridSystem(
        locations=[fast, slow],
        transitions=[to_slow, to_fast],
        initial_location=fast,
        initial_state=initial_state,
        parameters={"dwell_time": period / 2.0},
    )