Skip to content

time_varying_event_surface

Time-varying event-surface benchmark.

time_varying_event_surface(frequency=1.0, amplitude=0.5, hysteresis=0.2, drift=0.6, damping=0.4, initial_state=None)

Create a system with time-varying event-surface thresholds.

Parameters:

Name Type Description Default
frequency float

Frequency of the event-surface oscillation.

1.0
amplitude float

Amplitude of the event-surface oscillation.

0.5
hysteresis float

Event-surface hysteresis width.

0.2
drift float

Drift magnitude per location.

0.6
damping float

Damping on the second state.

0.4
initial_state ndarray | None

Optional initial state.

None

Returns:

Type Description
HybridSystem

HybridSystem with time-dependent event surfaces.

Source code in src/flowcean/hybrid/benchmarks/time_varying_event_surface.py
 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
def time_varying_event_surface(
    frequency: float = 1.0,
    amplitude: float = 0.5,
    hysteresis: float = 0.2,
    drift: float = 0.6,
    damping: float = 0.4,
    initial_state: np.ndarray | None = None,
) -> HybridSystem:
    """Create a system with time-varying event-surface thresholds.

    Args:
        frequency: Frequency of the event-surface oscillation.
        amplitude: Amplitude of the event-surface oscillation.
        hysteresis: Event-surface hysteresis width.
        drift: Drift magnitude per location.
        damping: Damping on the second state.
        initial_state: Optional initial state.

    Returns:
        HybridSystem with time-dependent event surfaces.
    """

    def flow_left(
        _t: float,
        state: np.ndarray,
        params: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        return np.array(
            [
                params["drift"] - 0.3 * state[0],
                -params["damping"] * state[1],
            ],
            dtype=float,
        )

    def flow_right(
        _t: float,
        state: np.ndarray,
        params: Parameters,
        _input_stream: InputStream,
    ) -> np.ndarray:
        return np.array(
            [
                -params["drift"] - 0.3 * state[0],
                -params["damping"] * state[1],
            ],
            dtype=float,
        )

    def event_surface_right(
        t: float,
        state: np.ndarray,
        params: Parameters,
        input_stream: InputStream,
    ) -> float:
        threshold = _threshold(t, params, input_stream)
        return state[0] - (threshold + 0.5 * params["hysteresis"])

    def event_surface_left(
        t: float,
        state: np.ndarray,
        params: Parameters,
        input_stream: InputStream,
    ) -> float:
        threshold = _threshold(t, params, input_stream)
        return state[0] - (threshold - 0.5 * params["hysteresis"])

    left_dynamics = ContinuousDynamics(flow_left, label="left")
    right_dynamics = ContinuousDynamics(flow_right, label="right")
    left = Location(left_dynamics, label="left")
    right = Location(right_dynamics, label="right")

    to_right = Transition(
        source=left,
        target=right,
        event=EventSurface(
            event_surface_right,
            direction=CrossingDirection.RISING,
            label="cross_right",
        ),
    )
    to_left = Transition(
        source=right,
        target=left,
        event=EventSurface(
            event_surface_left,
            direction=CrossingDirection.FALLING,
            label="cross_left",
        ),
    )

    if initial_state is None:
        initial_state = np.array([-1.0, 0.0], dtype=float)

    return HybridSystem(
        locations=[left, right],
        transitions=[to_right, to_left],
        initial_location=left,
        initial_state=initial_state,
        parameters={
            "frequency": frequency,
            "amplitude": amplitude,
            "hysteresis": hysteresis,
            "drift": drift,
            "damping": damping,
        },
    )