:math:`x(t+dt) = f(t, x(t), u(t), dt, \Theta)`
.. raw:: html

where :math:`x(t)` is :term:`state` at time :math:`t`, :math:`u(t)` is :term:`input` at time :math:`t` , :math:`dt` is the stepsize, and :math:`\Theta` are the model :term:`parameters` .
In a ProgPy model, this state transition can be represented one of two ways, either discrete or continuous, depending on the nature of state transition. In the case of continuous models, state transition behavior is defined by defining the first derivative, using the :py:func:`progpy.PrognosticsModel.dx` method. For discrete models, state transition behavior is defined using the :py:func:`progpy.PrognosticsModel.next_state` method. The continuous state transition behavior is recommended, because defining the first derivative enables some approaches that rely on that information.
.. image:: images/next_state.png
:width: 70 %
:align: center
.. image:: images/dx.png
:width: 70 %
:align: center
.. dropdown:: State transition equation example
An example of a state transition equation for a thrown object is included below. In this example, a model is created to describe an object thrown directly into the air. It has two states: position (x) and velocity (v), and no inputs.
.. code-block:: python
>>> def dx(self, x, u):
>>> # Continuous form
>>> dxdt = x['v']
>>> dvdt = -9.81 # Acceleration due to gravity
>>> return self.StateContainer({'x': dxdt, 'v': dvdt})
or, alternatively
.. code-block:: python
>>> def next_state(self, x, u, dt):
>>> # Discrete form
>>> new_x = x['x'] + x['v']*dt
>>> new_v = x['v'] -9.81*dt # Acceleration due to gravity
>>> return self.StateContainer({'x': new_x, 'v': new_v})
Output (Measurements)
^^^^^^^^^^^^^^^^^^^^^^^^^
The next important part of a prognostic model is the outputs. Outputs are measurable quantities of a system that are a function of system state. When applied in prognostics, generally the outputs are what is being measured or observed in some way. State estimators use the different between predicted and measured values of these outputs to estimate the system state.
Outputs are a function of only the system state (x) and :term:`parameters` (:math:`\Theta`), as described below. The expected outputs for a model are defined by its *outputs* property. The logic of calculating outputs from system state is provided by the user in the model :py:func:`progpy.PrognosticsModel.output` method.
.. image:: images/output.png
:width: 70 %
:align: center
.. raw:: html
:math:`z(t) = f(x(t), \Theta)`
.. raw:: html

.. dropdown:: Output equation example
An example of a output equation for a thrown object is included below. In this example, a model is created to describe an object thrown directly into the air. It has two states: position (x) and velocity (v). In this case we're saying that the position of the object is directly measurable.
.. code-block:: python
>>> def output(self, x):
>>> # Position is directly measurable
>>> position = x['x']
>>> return self.OutputContainer({'x': position})
Events
^^^^^^^^^^^^^^^^^^^^^^^^^^
Traditionally users may have heard the prognostic problem as estimating the Remaining Useful Life (RUL) of a system. ProgPy generalizes this concept with the concept of :term:`events
:math:`tm(t) = f(x(t), \Theta)`
.. raw:: html

:term:`Event states
:math:`es(t) = f(x(t), \Theta)`
.. raw:: html

If threshold_met is not specified, threshold_met is defined as when event_state is 0. Alternately, if event_state is not defined, it will be 0 when threshold_met is True, otherwise 1. If a model has events, at least one of these methods must be defined
.. dropdown:: Event Examples
An example of a event_state and threshold_met equations for a thrown object is included below. In this example, a model is created to describe an object thrown directly into the air. It has two states: position (x) and velocity (v). The event_state and threshold_met equations for this example are included below
.. code-block:: python
>>> def event_state(self, x):
>>> # Falling event_state is 0 when velocity hits 0, 1 at maximum speed
>>> falling_es = np.maximum(x['v']/self.parameters['throwing_speed'], 0)
>>>
>>> # Impact event_state is 0 when position hits 0,
>>> # 1 when at maximum height or when velocity is positive (going up)
>>> if x['v'] > 0:
>>> # Event state is 1 until falling starts
>>> x_max = 1
>>> else:
>>> # Use speed and position to estimate maximum height
>>> x_max = x['x'] + np.square(x['v'])/(-self.parameters['g']*2)
>>> impact_es = np.maximum(x['x']/x_max,0)
>>> return {'falling': falling_es, 'impact': impact_es}
.. code-block:: python
>>> def threshold_met(self, x):
>>> return {
>>> 'falling': x['v'] < 0,
>>> 'impact': x['x'] <= 0
>>> }
Parameters
^^^^^^^^^^^^^^^
Parameters are used to configure the behavior of a model. For parameterized :term:`physics-based