.. _dynamic-api-ref: ===================== Dynamic API Reference ===================== Complete API reference for NeurEco Dynamic models: ODE and ConvolutiveDynamic. .. contents:: On this page :local: :depth: 2 Import ====== .. code-block:: python from NeurEco import NeurEcoDynamic as dyn ODE === .. code-block:: python class dyn.ODE ODE-based model for time-series prediction. Learns hidden states to capture system dynamics. **File extension:** ``.ernn`` Constructor ----------- .. code-block:: python model = dyn.ODE(dll_path=None) **Parameters:** - ``dll_path`` *(str, optional)* — Path to NeurEco binaries Methods ------- build ^^^^^ .. code-block:: python status = model.build(config) Train the ODE model. **Parameters:** - ``config`` *(ODEBuildConfig)* — Build configuration **Returns:** ``int`` — Status code (0 = success) evaluate ^^^^^^^^ .. code-block:: python predictions = model.evaluate( excitations=None, init_excitations=None, init_outputs=None, *, time=None, init_time=None, ) Run inference on time-series data. **Parameters:** - ``excitations`` *(ndarray or list)* — Input/excitation arrays with **time in the first column** (shape ``(n_samples, 1 + n_inputs)`` or a list of such arrays) - ``init_excitations`` *(ndarray or list, optional)* — Initialization inputs, time in the first column - ``init_outputs`` *(ndarray or list, optional)* — Initialization outputs, time in the first column (required for explicit init) - ``time`` *(ndarray or list, optional, keyword-only)* — **Deprecated.** Separate time array(s); emits a ``DeprecatedParameterWarning`` and returns predictions without a leading time column - ``init_time`` *(ndarray or list, optional, keyword-only)* — **Deprecated.** Separate initialization time values **Returns:** ``ndarray`` or ``list`` — Predicted outputs, **time-first** (time in column 0) when ``excitations`` carries the time column **Note:** If initialization not provided, uses steady-state initialization. The deprecated separate-``time`` form returns predictions without a leading time column. The 4.x positional call ``evaluate(time, excitations, init_time, init_excitations, init_outputs)`` is still accepted for backward compatibility. It emits a ``DeprecatedParameterWarning`` and, like the ``time=`` keyword form, returns predictions without a leading time column. compute_error ^^^^^^^^^^^^^ .. code-block:: python error = dyn.ODE.compute_error(predictions, targets) Compute L2 relative error. **Static method.** **Parameters:** - ``predictions`` *(ndarray)* — Model predictions - ``targets`` *(ndarray)* — Ground truth **Returns:** ``float`` — L2 relative error load / save ^^^^^^^^^^^ .. code-block:: python model.load(path) model.save(path) Load or save model. **Parameters:** - ``path`` *(str)* — File path **Returns:** ``int`` — Status code get_input_count / get_output_count ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python n_inputs = model.get_input_count() n_outputs = model.get_output_count() Get number of input (excitation) and output features. **Returns:** ``int`` get_state_count ^^^^^^^^^^^^^^^ .. code-block:: python n_states = model.get_state_count() Get number of hidden states learned by the model. **Returns:** ``int`` get_number_of_init_tsteps ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python n_init = model.get_number_of_init_tsteps() Get number of time steps required for initialization. **Returns:** ``int`` get_steady_input / get_steady_output ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python steady_in = model.get_steady_input() steady_out = model.get_steady_output() Get steady-state input/output values. **Returns:** ``ndarray`` sensitivity ^^^^^^^^^^^ .. code-block:: python sens = model.sensitivity( time, excitations, id_output, initialization_time=None, initialization_excitations=None, initialization_outputs=None, ) Compute sensitivity of output with respect to inputs. .. note:: Unlike ``evaluate``, ``sensitivity`` takes the time as a **separate** ``time`` argument (it does not use the combined time-in-first-column form). **Parameters:** - ``time`` *(ndarray)* — Time array - ``excitations`` *(ndarray)* — Excitation (input) array - ``id_output`` *(int)* — Output index to analyze - ``initialization_time`` / ``initialization_excitations`` / ``initialization_outputs`` — Optional initialization arrays **Returns:** ``ndarray`` — Sensitivity values export_fmu ^^^^^^^^^^ .. code-block:: python status = model.export_fmu(path) Export to FMU format. **Parameters:** - ``path`` *(str)* — Output .fmu file path **Returns:** ``int`` — Status code .. note:: Requires NeurEco Embed license. get_number_of_networks_from_checkpoint ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python n = model.get_number_of_networks_from_checkpoint(path) Get number of models saved in a checkpoint. **Parameters:** - ``path`` *(str)* — Checkpoint path **Returns:** ``int`` — Number of checkpointed models load_model_from_checkpoint ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python model.load_model_from_checkpoint(path, model_index) Load a specific model from checkpoint. **Parameters:** - ``path`` *(str)* — Checkpoint path - ``model_index`` *(int)* — Model index (0-based) The build log and the GUI number checkpoints from 1: "Checkpoint N" there is ``model_index`` N - 1 here. delete ^^^^^^ .. code-block:: python model.delete() Free native memory. **Always call when done.** ODEBuildConfig ============== .. code-block:: python # Each array: column 0 = time, remaining columns = excitations / outputs. config = dyn.ODEBuildConfig( # Required (time-first arrays) train_exc_list, train_out_list, # Optional (time-first arrays) valid_exc_list=None, valid_out_list=None, test_exc_list=None, test_out_list=None, valid_percentage=30, write_model_to="model", checkpoint_address="ckpt", inputs_shifting="mean", inputs_scaling="l2", outputs_shifting="mean", outputs_scaling="l2", inputs_normalize_per_feature=True, outputs_normalize_per_feature=True, steady_state_exc=None, steady_state_out=None, min_hidden_states=1, max_hidden_states=0, resume=False, ) **Parameters:** .. list-table:: :header-rows: 1 :widths: 30 15 55 * - Parameter - Default - Description * - ``train_exc_list`` - (required) - List of excitation (input) arrays; column 0 is time, remaining columns are inputs * - ``train_out_list`` - (required) - List of output arrays; column 0 is time, remaining columns are outputs * - ``valid_exc_list`` - ``None`` - Validation excitation arrays (time in the first column) * - ``valid_out_list`` - ``None`` - Validation output arrays (time in the first column) * - ``valid_percentage`` - ``30`` - Validation split (if no validation data) * - ``steady_state_exc`` - ``None`` - Steady-state input values (1D array) * - ``steady_state_out`` - ``None`` - Steady-state output values (1D array) * - ``min_hidden_states`` - ``1`` - Minimum hidden states * - ``max_hidden_states`` - ``0`` - Maximum hidden states (0 = no limit) * - ``inputs_shifting`` - ``"mean"`` - Input shift: ``"none"``, ``"mean"`` * - ``inputs_scaling`` - ``"l2"`` - Input scale: ``"none"``, ``"l2"``, ``"max"`` * - ``outputs_shifting`` - ``"mean"`` - Output shift (same options as ``inputs_shifting``) * - ``outputs_scaling`` - ``"l2"`` - Output scale (same options as ``inputs_scaling``) * - ``inputs_normalize_per_feature`` - ``True`` - Normalize each input feature independently * - ``outputs_normalize_per_feature`` - ``True`` - Normalize each output feature independently * - ``resume`` - ``False`` - ``True``: continue the build stored in ``checkpoint_address`` where it stopped. A resumed build gives the same models as a build without pause (see :ref:`dynamic-resume`) .. note:: **Deprecated separate-time parameters.** ``train_time_list``, ``valid_time_list`` and ``test_time_list`` (lists of 1-D time arrays passed alongside pure excitation/output arrays) remain accepted for backward compatibility but emit a ``DeprecatedParameterWarning``. Prefer placing the time in the first column of each excitation and output array. ConvolutiveDynamic ================== .. code-block:: python class dyn.ConvolutiveDynamic Convolutional Dynamic model for time-series prediction: a convolutional neural network applied to a sliding window of past inputs. In the GUI, this is the **CNN Dynamic** template. **File extension:** ``.ecnn`` Constructor ----------- .. code-block:: python model = dyn.ConvolutiveDynamic(dll_path=None) Methods ------- Same methods as ODE, with these additions/differences: get_window_size ^^^^^^^^^^^^^^^ .. code-block:: python w_size = model.get_window_size() Get the window size: the number of time steps the network reads to make one prediction. **Returns:** ``int`` **Note:** Predictions start at time step ``window_size - 1`` (the window provides context for the first prediction). evaluate ^^^^^^^^ Same as ODE, but no initialization parameters needed. ``excitations`` carries the time in its first column and predictions are returned time-first: .. code-block:: python predictions = model.evaluate(excitations) The model predicts every time step from the ``window_size``-th one on, whatever the ``window_stride`` used for training. ConvolutiveDynamicBuildConfig ============================= .. code-block:: python # Each array: column 0 = time, remaining columns = excitations / outputs. config = dyn.ConvolutiveDynamicBuildConfig( # Required (time-first arrays) train_exc_list, train_out_list, # Optional (same as ODE plus:) window_size=32, # ... other parameters same as ODEBuildConfig ) **Additional Parameters:** - ``window_size`` *(int)* — Convolution window size, at least 3 (default: 32) - ``window_stride`` *(int)* --- Training data only: step between two consecutive training windows (default: 1). The model still predicts every time step. - ``resume`` *(bool)* --- ``True``: continue the build stored in ``checkpoint_address`` instead of starting a new one (default: ``False``). See :ref:`dynamic-resume`. The network architecture parameters (``hidden_layer_number``, ``layer_multiplier``, ``last_layer_grid_number``, ``tol_last_layer``) and the padding parameters are described in :ref:`convolutive-building`. The deprecated ``train_time_list`` / ``valid_time_list`` / ``test_time_list`` separate-time parameters behave the same way as for ``ODEBuildConfig``. .. important:: ConvolutiveDynamic requires **uniformly spaced time steps** within and across all trajectories. ODE does not have this requirement — its time arrays only need to be **sorted in strictly increasing order** (non-uniform spacing is allowed). Example Usage ============= ODE Model --------- .. code-block:: python from NeurEco import NeurEcoDynamic as dyn import numpy as np # Prepare data (lists of arrays for multiple trajectories, time in column 0) t = np.arange(0, 10, 0.01) train_exc = [np.column_stack([t, np.random.randn(1000, 3)])] # time + 3 inputs train_out = [np.column_stack([t, np.random.randn(1000, 2)])] # time + 2 outputs # Build # Each array: column 0 = time, remaining columns = excitations / outputs. model = dyn.ODE() config = dyn.ODEBuildConfig( train_exc_list=train_exc, train_out_list=train_out, write_model_to="./ode_model.ernn" ) model.build(config) # Evaluate (steady-state init) # test_exc has time in its first column; predictions are returned time-first. predictions = model.evaluate(test_exc) # Evaluate with explicit initialization n_init = model.get_number_of_init_tsteps() predictions = model.evaluate( test_exc[n_init-1:], init_excitations=test_exc[:n_init], init_outputs=test_out[:n_init] ) model.delete() Convolutional Dynamic Model --------------------------- .. code-block:: python from NeurEco import NeurEcoDynamic as dyn import numpy as np # Build # Each array: column 0 = time, remaining columns = excitations / outputs. model = dyn.ConvolutiveDynamic() config = dyn.ConvolutiveDynamicBuildConfig( train_exc_list=train_exc, train_out_list=train_out, window_size=32, write_model_to="./conv_model.ecnn" ) model.build(config) # Evaluate # test_exc has time in its first column; predictions are returned time-first. predictions = model.evaluate(test_exc) # Note: predictions start at time step (window_size - 1) w_size = model.get_window_size() aligned_ref = test_out[w_size - 1:] # compute_error takes outputs only, so drop the leading time column from both. error = model.compute_error(predictions[:, 1:], aligned_ref[:, 1:]) model.delete() Parametric ODE Model -------------------- For parameters that stay constant within a trajectory but vary between experiments: .. code-block:: python # Replicate constant parameter across all time steps k_value = 2.5 # Constant parameter n_steps = 1000 # Create excitation with parametric input (time in column 0) time_column = np.linspace(0, 10, n_steps) k_column = np.full(n_steps, k_value) force_column = np.sin(np.linspace(0, 10, n_steps)) excitation = np.column_stack([time_column, k_column, force_column]) # Build and evaluate as normal