Linear Time-Invariant (LTI) Systems

Much of network control assumes the state dynamics follow a linear time-invariant model.

x(t+1) = Ax(t) + Bu(t)

or the continuous time analog

\dot{x}(t) = Ax(t) + Bu(t).

These functions provide assistive functions to help with the transition from a network model to a linear systems model as well as facilitate generating specific realizations of a LTI system (with weights) from a structured network.

netcontrolz.kalman_generic_rank(G, controls[, repeats=None])[source]

Finds the reachability corresponding to a graph G (adjacency matrix A) and its controls (a list of tuples of node objects) by brute force computing the Kalman rank condition:

rank [B\ AB\ A^2B\ A^3B\ \cdots\ A^{(n-1)}B].

In order to compute the rank generically, we generate random entries for A and B, subject to their zero/non-zero sparsity patterns and compute the true rank. We repeat this repeats times (default is 100) and return the largest value.

netcontrolz.kalman_generic_rank_(G, controls[, repeats=None])[source]

Finds the reachability corresponding to a graph G (adjacency matrix A) and its controls (a list of tuples of node indices) by brute force computing the Kalman rank condition:

rank [B\ AB\ A^2B\ A^3B\ \cdots\ A^{(n-1)}B].

In order to compute the rank generically, we generate random entries for A and B, subject to their zero/non-zero sparsity patterns and compute the true rank. We repeat this repeats times (default is 100) and return the largest value.

netcontrolz.controls_idx(G, controls)[source]

Convenience function to return the list of tuples of control indices of a network G corresponding to the list of tuples of node objects in controls.

netcontrolz.input_matrix(G, controls[, m=None])[source]

Returns the n x m input matrix B corresponding to the list of tuples controls of node indices that are driven by the controls, where n is the number of nodes in the network G (if G is not compact, then the size n may be larger than the number of nodes). If m is not specified, then m is taken as the number of controls (i.e., the length of controls).

netcontrolz.input_matrix_(n, controls[, m=None])[source]

Returns the n x m input matrix B corresponding to the list of tuples controls of node indices that are driven by the controls. If m is not specified, then m is taken as the number of controls (i.e., the length of controls).

netcontrolz.matrix_realization(M, a, b)[source]

Returns a matrix with the same sparsity pattern as the matrix M where nonzero elements of M are uniformly randomly selected from the interval [a,b].

netcontrolz.fix_diagonals(M, d)[source]

Returns M with diagonal elements set to be:

M_{ii} = -(d + \sum_{j=1}^n M_{ij})

which is simply just a perturbation d away from the row sum of M. Selecting d > 0 ensures the eigenvalues of a symmetric matrix are negative.