Skip to content
FICTION-ZJUPublic

About

Derivative-agnostic inference of nonlinear hybrid automata

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

 

History

144 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dainarx

Dainarx is a prototypical tool for the derivative-agnostic inference of nonlinear hybrid automata with high-order NARX-modeled dynamics from input-output discrete-time traces of hybrid systems.

The extended version for noisy data: Dainarx-Noisy.

  • Python 3.9

Install the dependencies:

pip install numpy scikit-learn networkx matplotlib

"scikit-learn" is used for SVM learning, while "networkx" is only used to compute test metrics. "matplotlib" is used for plotting images.

Run:

python main.py

You can change the path in main.py to test different automata.

If you want to test all the automata, run the following command:

python test_all.py

The system will generate evaluation_log.csv in the root directory, recording all the test results.

  • The "data" folder stores the traces generated by the code.
  • The "automata" folder stores automaton data.
  • The json format of the automaton data is as follows.
{
  "automaton": {      // Automaton.
    "var": "x1, x2",  // List of output variables, separated by ','.
    "input": "u",     // List of input variables, separated by ','.
    "mode": [         // A list of automata modes.
      {
        "id": 1,      // The id of the mode.
        "eq": "x1[1] = 1, x2[2] = -3 * x2[1] - 25 * x2[0] + u"
        // Eq represents the ode of each variable in this mode, separated by ','.
        // Variables that are not defined in "var" and "input" cannot appear.
        // x[k] represents the KTH derivative of x. The input variable u directly represents the value of u.
        // The left side of the equal sign is the highest-order differential, and the right side is the expression. Implicit functions are not supported.
        // ode must be provided for each variable.
      },
      {
        "id": 2,
        "eq": "x1[1] = -1, x2[2] = -3 * x2[1] - 25 * x2[0]"
      }
    ],
    "edge": [
      {
        "direction": "1 -> 2",  // The edge from mode u to mode v, represented as "u -> v".
        "condition": "x1 >= 5", // Transition conditions. Variables that are not defined in "var" and "input" cannot appear.
        "reset": {              // Reset function.
          "x1": ["x1[0] - 1"]
          // The representation structure is the same as "init_state", and the meaning of the expression is the same as "eq".
          // An empty string ("") indicates that the item has not been reset (not modified). Variables/items that do not appear will be padded with an empty string.
        }
      },
      {
        "direction": "2 -> 1",
        "condition": "x1 <= 0"
      }
    ]
  },
  "init_state": [ // The initial state list, with several initial states generating several trajectory data.
    {
      "mode": 1,  // Initial mode.
      "x1": [0],  // The initial state of x1, where "[a, b, c, ...]" represents the initial states of x1[0], x1[1], x1[2], and so on.
      "x2": [0],  // If no initial state is provided, or if the number of initial states provided is insufficient for the order of the equation, zeros are automatically added backward.
      "u": "2 + 1.5 * sin(t)" // The expression of each input, a function related to t.
    },
    {
      "mode": 1,
      "x1": [2],
      "x2": [3],
      "u": "1 + sin(t)"
    }
  ],
  "config": {                   // Parameter List.
    "dt": 0.01,                 // Discrete time step, default is 0.01.
    "total_time": 10.0,         // Total sampling time, default is 10.
    "order": 3,                 // Order of the difference equation, default is 3.
    "window_size": 10,          // Size of the sliding window, default is 10.
    "clustering_method": "fit", // Clustering method, default is "fit", options are "fit" and "dis".
    "minus": false,             // Whether to minimize the order, default is false.
    "need_bias": true,          // Whether a constant term is needed, default is true.
    "kernel": "linear",         // SVM kernel function, default is "linear".
    "other_items": "",          // Other nonlinear or cross terms in the difference equation, default is empty.
    "svm_c": 1e6,               // SVM parameter C, default is 1e6.
    "self_loop": false,         // Whether self-loops are allowed, default is false.
    "need_reset": false,        // Whether to learn reset, default is false; recommended to enable if order > 1.
    "class_weight": 1.0         // Weight of negative samples in SVM (positive sample = 1.0), default is 1.0.

    // Explanation of other_items:
    // Example: "x0, x2, x3: x[1] * x_[?]; x[?] * x1[2]"
    // Expressions are separated by semicolons (;).
    // The part before the colon (:) defines the scope of the expression; "xi" means it applies to the i-th variable (starting from 0). If no scope is provided, it applies to all variables.
    // "x" refers to the variable itself, "x_" refers to any other variable except itself, "xi" refers to the i-th variable.
    // "x[1]" means x[t - 1], "x[a]" means x[t - a], representing past values in the difference equation. Terms with lag greater than order or zero are not allowed.
    // "x[?]" represents any lag term in the range [1, order].

    // Example:
    // order = 2, other_items = "x0, x2: x[1] * x_[?]"
    // For x0, the following additional terms will be fitted:
    //   x0[1] * x1[1], x0[1] * x1[2], x0[1] * x2[1], x0[1] * x2[2].
    // For x1, no additional terms will be fitted.
    // For x2, the following additional terms will be fitted:
    //   x2[1] * x0[1], x2[1] * x0[2], x2[1] * x1[1], x2[1] * x1[2].
  }
}

About

Derivative-agnostic inference of nonlinear hybrid automata

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages