Chapter 7: Fundamentals of Stability Analysis

Lesson 2: Pole Locations and Asymptotic Stability

This lesson develops the precise relationship between pole locations of a linear time-invariant (LTI) system and different notions of stability, with emphasis on asymptotic stability. We connect time-domain solutions, transfer functions, and state-space eigenvalues, and show how simple computational tools in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica can be used to assess stability of control systems, including basic robot joint models.

1. From Transfer Function to Pole-Based Stability Conditions

Consider a causal, single-input single-output (SISO) LTI system with transfer function (already introduced in earlier chapters)

\[ G(s) = \frac{N(s)}{D(s)} = \frac{b_m s^m + \cdots + b_1 s + b_0} {s^n + a_{n-1} s^{n-1} + \cdots + a_1 s + a_0}, \quad n \ge m. \]

The poles of the system are the roots of \( D(s) \), i.e., the complex numbers \( p_1, \dots, p_r \) (counted with multiplicity) such that \( D(p_i) = 0 \). Assuming proper rational \( G(s) \) with all poles in the open left half-plane (OLHP), the impulse response \( g(t) \) is absolutely integrable, and the system is BIBO stable (recall from Lesson 1).

For distinct poles, a partial fraction expansion yields

\[ G(s) = \sum_{i=1}^n \frac{K_i}{s - p_i} \quad \Longrightarrow \quad g(t) = \mathcal{L}^{-1}\{G(s)\}(t) = \sum_{i=1}^n K_i e^{p_i t} u(t), \]

where \( u(t) \) is the unit step. Writing \( p_i = \sigma_i + j \omega_i \), each mode behaves as \( e^{\sigma_i t} \) times a sinusoid. Thus the real part \( \sigma_i = \Re(p_i) \) controls exponential decay or growth.

As introduced in Lesson 1, an LTI system is asymptotically stable if, for zero input, any state trajectory and output converge to zero as \( t \rightarrow \infty \). We now formulate a precise characterization in terms of poles.

2. General Partial Fraction Expansion and Repeated Poles

In general, poles may be repeated. Let \( p_1,\dots,p_r \) be the distinct poles with multiplicities \( m_1,\dots,m_r \), such that \( \sum_{i=1}^r m_i = n \). Then one can write

\[ G(s) = \sum_{i=1}^r \sum_{k=1}^{m_i} \frac{K_{ik}}{(s - p_i)^k}. \]

Using standard Laplace transform tables, we obtain the impulse response

\[ g(t) = \sum_{i=1}^r \sum_{k=1}^{m_i} K_{ik}\,\frac{t^{k-1}}{(k-1)!} e^{p_i t} u(t), \quad t \ge 0. \]

Again, if we write \( p_i = \sigma_i + j \omega_i \), then the magnitude of each term scales like \( |t^{k-1} e^{\sigma_i t}| = t^{k-1} e^{\sigma_i t} \).

  • If \( \sigma_i < 0 \), then \( t^{k-1} e^{\sigma_i t} \rightarrow 0 \) as \( t \rightarrow \infty \), even for repeated poles (\( k >1 \)), due to exponential dominance.
  • If \( \sigma_i > 0 \), the contribution grows without bound (exponentially).
  • If \( \sigma_i = 0 \) and \( k = 1 \), the term is bounded but oscillatory (pure sinusoid).
  • If \( \sigma_i = 0 \) and \( k \ge 2 \), the term grows polynomially in \( t \), hence unbounded.

This qualitative behavior underlies the full pole-based characterization of asymptotic stability and marginal stability.

3. Theorem — Pole Location and Asymptotic Stability

We now state a fundamental result for proper rational SISO LTI systems.

Theorem 1 (Pole condition for asymptotic stability).

Let \( G(s) \) be a proper rational transfer function with poles \( p_i \) (including multiplicities). The corresponding LTI system is asymptotically stable if and only if

\[ \Re(p_i) < 0 \quad \text{for all poles } p_i. \]

Sketch of proof (sufficiency).

Using the representation from the previous section,

\[ g(t) = \sum_{i=1}^r \sum_{k=1}^{m_i} K_{ik} \frac{t^{k-1}}{(k-1)!} e^{p_i t} u(t), \quad p_i = \sigma_i + j \omega_i. \]

If \( \Re(p_i) = \sigma_i < 0 \) for all \( i \), then there exists a constant \( \alpha > 0 \) with \( \sigma_i \le -\alpha < 0 \) for all \( i \). Hence

\[ \big| t^{k-1} e^{p_i t} \big| = t^{k-1} e^{\sigma_i t} \le t^{k-1} e^{-\alpha t}. \]

The function \( t^{k-1} e^{-\alpha t} \) is absolutely integrable on \( [0,\infty) \) and tends to zero as \( t \rightarrow \infty \). Because \( g(t) \) is a finite sum of such terms, \( g(t) \rightarrow 0 \) as \( t \rightarrow \infty \). As shown in Lesson 1, asymptotic decay of the homogeneous (zero-input) solution for any initial condition is equivalent to asymptotic stability.

Sketch of proof (necessity).

  • If some pole \( p^\star \) satisfies \( \Re(p^\star) > 0 \), then \( e^{p^\star t} \) grows exponentially; by choosing initial conditions (or inputs) that excite the corresponding mode (nonzero residue), the state and output grow without bound, so the system is unstable.
  • If some pole satisfies \( \Re(p^\star) = 0 \) with multiplicity \( m \ge 2 \), then the corresponding term in the impulse response behaves like \( t^{m-1} \cos(\omega t) \) or \( t^{m-1} \sin(\omega t) \), which diverges in magnitude as \( t \rightarrow \infty \). Hence not asymptotically stable.

Thus all poles must satisfy \( \Re(p_i) < 0 \).

Remark (marginal stability).

If all poles satisfy \( \Re(p_i) \le 0 \), with any pole on the imaginary axis being simple and no repeated imaginary-axis poles, then the modes are bounded sinusoids plus decaying terms. The system is then often called marginally stable (internally), but not asymptotically stable, because trajectories do not converge to zero.

4. State-Space View — Eigenvalues and Matrix Exponential

For a state-space model

\[ \dot{\mathbf{x}}(t) = A \mathbf{x}(t) + B \mathbf{u}(t), \quad \mathbf{y}(t) = C \mathbf{x}(t) + D \mathbf{u}(t), \]

the homogeneous solution (zero input) is

\[ \mathbf{x}(t) = e^{A t} \mathbf{x}(0). \]

Using the Jordan canonical form, one can write

\[ A = V J V^{-1}, \quad e^{A t} = V e^{J t} V^{-1}, \]

where \( J \) is block-diagonal with Jordan blocks. Each Jordan block of size \( m \) associated with eigenvalue \( \lambda \) contributes terms of the form \( t^k e^{\lambda t} \), \( 0 \le k \le m-1 \).

Theorem 2 (Eigenvalue test).

The origin of the state-space system is asymptotically stable if and only if all eigenvalues \( \lambda_i(A) \) satisfy

\[ \Re(\lambda_i(A)) < 0 \quad \text{for all } i. \]

This is the state-space analogue of Theorem 1. For a minimal realization, the poles of \( G(s) \) coincide with the eigenvalues of \( A \), so the two tests are equivalent in that setting.

In robotics, linearization of a nonlinear robot joint model around an operating point yields a matrix \( A \) whose eigenvalues determine whether small perturbations of joint positions and velocities decay (stable) or grow (unstable).

5. s-Plane Classification of Pole Configurations

For a SISO LTI system, stability properties can be read from the location of poles in the complex \( s \)-plane:

  • Asymptotically stable: all poles strictly in the left half-plane (\( \Re(p_i) < 0 \)).
  • Unstable: at least one pole with \( \Re(p_i) > 0 \), or any pole on the imaginary axis with multiplicity \( \ge 2 \).
  • Marginally stable (internally): poles in the closed left half-plane, at least one simple pole on the imaginary axis, and no repeated imaginary-axis poles.

For second-order systems (already studied in Chapter 6), \( s^2 + 2 \zeta \omega_n s + \omega_n^2 = 0 \) has poles \( s = -\zeta \omega_n \pm j \omega_n \sqrt{1 - \zeta^2} \). Asymptotic stability requires \( \zeta > 0 \). Values of \( \zeta \) control the damping behavior but not the basic stability classification (as long as \( \zeta > 0 \)).

flowchart TD
  START["Given transfer function or A matrix"] --> TF{"Work with \ntransfer function?"}
  TF -->|yes| TF1["Compute denominator D(s)"]
  TF1 --> TF2["Find roots of D(s) (poles)"]
  TF -->|no| SS1["Compute eigenvalues of A"]
  TF2 --> CLASS["Classify by pole real parts"]
  SS1 --> CLASS
  CLASS --> STAB["All poles: Re < 0  → \nasymptotically stable"]
  CLASS --> MARG["Poles in left \nhalf-plane but some on \nimaginary axis (simple) → marginal"]
  CLASS --> UNST["Any pole with Re > 0 or repeated \non imaginary axis → unstable"]
        

6. Algorithmic Stability Check (Practical Flow)

In practice, stability checking follows a straightforward computational pipeline that is directly implementable in software:

  1. Obtain a transfer function \( G(s) \) or a state-space realization \( (A,B,C,D) \) by modeling or identification.
  2. Form the characteristic polynomial \( D(s) = \det(s I - A) \) or read it directly from the denominator of \( G(s) \).
  3. Numerically compute the roots of \( D(s) \) or the eigenvalues of \( A \) using robust numerical linear algebra routines.
  4. Test the real parts of all poles: \( \Re(p_i) < 0 \) implies asymptotic stability.
  5. Optionally, verify the conclusion by simulating time responses (e.g., step response) to observe convergence or divergence.
flowchart TD
  M["Model dynamics (mechanical, electrical, robot joint)"] --> R["Form G(s) or (A,B,C,D)"]
  R --> E["Compute poles / eigenvalues numerically"]
  E --> C{"Re(p_i) < 0 for all i?"}
  C -->|yes| STABLE["System is asymptotically stable"]
  C -->|no| UNSTABLE["System is NOT asymptotically stable"]
        

7. Python Implementation — Poles and Stability Check

Python, together with the python-control library and robotics-focused packages such as roboticstoolbox, provides convenient tools for stability analysis of robot joints or actuators.

Consider a simple DC-motor-driven rotational joint with transfer function from motor torque command to joint angle (simplified model):

\[ J \ddot{\theta}(t) + b \dot{\theta}(t) = u(t), \quad G(s) = \frac{\Theta(s)}{U(s)} = \frac{1}{J s^2 + b s}. \]

The open-loop poles are at \( s = 0 \) and \( s = -\tfrac{b}{J} \), so the system is only marginally stable. A feedback controller will shift these poles. Below is Python code to construct such a system and check stability:


import numpy as np
import control  # python-control
# Optional: robotics toolbox for more complex robot models
# from roboticstoolbox import DHRobot, RevoluteDH

# Physical parameters
J = 0.01   # inertia
b = 0.1    # viscous friction

# Open-loop transfer function G(s) = 1 / (J s^2 + b s)
num = [1.0]
den = [J, b, 0.0]
G = control.TransferFunction(num, den)

print("Open-loop transfer function G(s):")
print(G)

poles = control.pole(G)
print("Poles:", poles)

def classify_poles(p):
    if np.any(np.real(p) > 0.0):
        return "unstable"
    if np.any(np.isclose(np.real(p), 0.0)):
        return "marginally stable (not asymptotically stable)"
    return "asymptotically stable"

print("Stability classification:", classify_poles(poles))

# Example: add simple proportional feedback on angle (position control)
Kp = 5.0
# Unity feedback: closed-loop from reference to angle
G_cl = control.feedback(Kp * G, 1)
poles_cl = control.pole(G_cl)
print("Closed-loop poles:", poles_cl)
print("Closed-loop stability:", classify_poles(poles_cl))

# For robotics, one can obtain linearized joint dynamics matrices (A,B)
# from more complex models and use:
# eigvals, _ = np.linalg.eig(A)
# print("Eigenvalues of A:", eigvals)
# print("State-space stability:", classify_poles(eigvals))
      

This pattern extends to multi-DOF robotic manipulators: linearize about a configuration, construct \( A \) and \( B \), and use eigenvalue computations to check local stability of joint controllers.

8. C++ Implementation — Eigen and ROS Ecosystem

In C++, linear algebra for stability analysis is commonly handled using Eigen. In robotics applications built on ROS, controllers (e.g., ros_control) often maintain an internal state-space model and use Eigen-based computations for eigenvalues.

Below we consider a 2-state robot joint model \( \dot{\mathbf{x}} = A \mathbf{x} \), where \( \mathbf{x} = [\theta, \dot{\theta}]^\top \). The stiffness \( k \) and damping \( b \) are controller-dependent parameters.

\[ A = \begin{bmatrix} 0 & 1 \\ -\tfrac{k}{J} & -\tfrac{b}{J} \end{bmatrix}. \]


#include <iostream>
#include <complex>
#include <Eigen/Dense>

std::string classifyEigenvalues(const Eigen::VectorXcd& evals) {
    bool hasPositive = false;
    bool hasImagAxisRepeated = false;
    int imagAxisCount = 0;

    for (int i = 0; i < evals.size(); ++i) {
        double real_part = evals(i).real();
        double imag_part = evals(i).imag();

        if (real_part > 0.0) {
            hasPositive = true;
        }
        if (std::abs(real_part) < 1e-9 && std::abs(imag_part) > 1e-9) {
            imagAxisCount++;
        }
    }

    if (hasPositive) return "unstable";
    if (imagAxisCount >= 1) {
        // Here we ignore multiplicity check for simplicity
        return "marginally stable or oscillatory";
    }
    return "asymptotically stable";
}

int main() {
    double J = 0.01;
    double b = 0.1;
    double k = 2.0;   // stiffness from PD-like position control

    Eigen::Matrix2d A;
    A << 0.0,              1.0,
          -k / J,   -b / J;

    Eigen::EigenSolver<Eigen::Matrix2d> es(A);
    Eigen::VectorXcd evals = es.eigenvalues();

    std::cout << "Eigenvalues of A:\n";
    for (int i = 0; i < evals.size(); ++i) {
        std::cout << evals(i) << std::endl;
    }

    std::cout << "Stability: " << classifyEigenvalues(evals) << std::endl;

    // In a ROS controller, this logic could be called whenever gains change
    // to ensure the joint-level closed-loop dynamics remain stable.
    return 0;
}
      

By adjusting \( k \) and \( b \), we move the eigenvalues of \( A \) in the complex plane. Ensuring both eigenvalues lie in the left half-plane guarantees asymptotic stability of the linearized joint dynamics.

9. Java Implementation — Eigenvalues via EJML / Commons Math

Java-based robotic frameworks (e.g., some educational platforms and FIRST robotics libraries) often rely on linear algebra libraries such as EJML or Apache Commons Math. The stability test is analogous: compute eigenvalues of \( A \) and check their real parts.


// Example using Apache Commons Math
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.EigenDecomposition;

public class StabilityCheck {

    public static String classifyEigenvalues(double[] real, double[] imag) {
        boolean hasPositive = false;
        boolean hasImagAxis = false;

        for (int i = 0; i < real.length; i++) {
            if (real[i] > 0.0) {
                hasPositive = true;
            }
            if (Math.abs(real[i]) < 1e-9 && Math.abs(imag[i]) > 1e-9) {
                hasImagAxis = true;
            }
        }

        if (hasPositive) return "unstable";
        if (hasImagAxis) return "marginally stable (oscillatory)";
        return "asymptotically stable";
    }

    public static void main(String[] args) {
        double J = 0.01;
        double b = 0.1;
        double k = 3.0;

        double[][] dataA = {
                {0.0,          1.0},
                {-k / J,  -b / J}
        };
        RealMatrix A = new Array2DRowRealMatrix(dataA);
        EigenDecomposition ed = new EigenDecomposition(A);

        int n = A.getRowDimension();
        double[] real = new double[n];
        double[] imag = new double[n];

        for (int i = 0; i < n; i++) {
            real[i] = ed.getRealEigenvalue(i);
            imag[i] = ed.getImagEigenvalue(i);
            System.out.println("lambda_" + i + " = " + real[i] + " + j" + imag[i]);
        }

        String stability = classifyEigenvalues(real, imag);
        System.out.println("Stability: " + stability);

        // This pattern can be embedded in Java-based robotic control loops
        // to verify that gain updates preserve closed-loop stability.
    }
}
      

The key idea is independent of the language: numerical eigenvalue routines allow a direct implementation of the theoretical test \( \Re(\lambda_i) < 0 \).

10. MATLAB/Simulink Implementation for Robot Joints

MATLAB, together with Control System Toolbox and Robotics System Toolbox, is widely used in control and robotics. The function pole (for transfer functions) and eig (for state-space models) directly expose pole locations.


% Parameters for a simple robot joint model
J = 0.01;
b = 0.1;

% Transfer function from torque to angle
num = 1;
den = [J, b, 0];  % J s^2 + b s

G = tf(num, den);
disp('Open-loop poles:');
p_open = pole(G)

% Simple proportional position controller
Kp = 5;
G_cl = feedback(Kp * G, 1);
disp('Closed-loop poles:');
p_cl = pole(G_cl)

% Stability classification (vectorized logic)
if any(real(p_cl) > 0)
    disp('Closed-loop system is unstable');
elseif any(abs(real(p_cl)) < 1e-6)
    disp('Closed-loop system is marginally stable (not asymptotically stable)');
else
    disp('Closed-loop system is asymptotically stable');
end

% State-space form and eigenvalues
[A, B, C, D] = ssdata(G_cl);
lambda = eig(A)

% Simulink note:
% A Simulink model of the robot joint (with actuator, sensor, and controller)
% can be linearized around an operating point using:
% sys_lin = linearize('robot_joint_model', io);
% pole(sys_lin)
      

For multi-DOF manipulators modeled via rigidBodyTree, one can linearize around a configuration using Robotics System Toolbox and apply the same pole/eigenvalue-based stability test.

11. Wolfram Mathematica Implementation

Wolfram Mathematica provides symbolic and numerical tools for poles, eigenvalues, and system plots.


(* Parameters *)
J = 0.01;
b = 0.1;

(* Transfer function model *)
G = TransferFunctionModel[1/(J s^2 + b s), s];

(* Poles of the open-loop system *)
polesOpen = Poles[G]

(* Simple proportional feedback with gain Kp *)
Kp = 5;
Gcl = SystemsModelFeedbackConnect[Kp G, 1];

polesCL = Poles[Gcl]
Print["Closed-loop poles: ", polesCL];

(* Stability classification *)
If[Max[Re[polesCL]] > 0,
   Print["Closed-loop unstable"],
   If[Max[Re[polesCL]] == 0,
      Print["Closed-loop marginally stable"],
      Print["Closed-loop asymptotically stable"]
   ]
];

(* State-space form and eigenvalues *)
ss = StateSpaceModel[Gcl];
eigA = Eigenvalues[ss["A"]]
      

For more complex robot models, one can use StateSpaceModel of linearized dynamics and then apply Eigenvalues to check asymptotic stability conditions.

12. Problems and Solutions

Problem 1 (Poles and Asymptotic Stability).

Consider the transfer function \( G(s) = \frac{4}{s^3 + 5 s^2 + 6 s} \). (a) Find the poles. (b) Classify the system as asymptotically stable, marginally stable, or unstable.

Solution.

Factor the denominator:

\[ s^3 + 5 s^2 + 6 s = s (s^2 + 5 s + 6) = s (s+2)(s+3). \]

Thus the poles are \( p_1 = 0 \), \( p_2 = -2 \), and \( p_3 = -3 \). One pole is at the origin (\( \Re(p_1) = 0 \)) and is simple, while the others are in the left half-plane.

The time response contains a term proportional to \( u(t) \) (from the pole at zero), which does not decay to zero but remains bounded. Therefore, the system is marginally stable internally, but not asymptotically stable.

Problem 2 (Second-Order Robot Joint Model).

A single robot joint with inertia \( J > 0 \) and viscous friction \( b \ge 0 \) is controlled by a proportional position controller of gain \( K_p > 0 \). The resulting closed-loop characteristic polynomial is

\[ J s^2 + b s + K_p = 0. \]

Derive conditions on \( J, b, K_p \) for asymptotic stability.

Solution.

For a second-order polynomial \( J s^2 + b s + K_p = 0 \) with \( J > 0 \), the roots have negative real parts if and only if all coefficients are positive:

\[ J > 0, \quad b > 0, \quad K_p > 0. \]

Thus asymptotic stability requires strictly positive damping and strictly positive proportional gain. If \( b = 0 \), the roots lie on the imaginary axis (pure oscillation) and the system is only marginally stable. If \( K_p \le 0 \), one root lies in the right half-plane, yielding instability.

Problem 3 (Repeated Imaginary-Axis Pole).

Show that a transfer function with a second-order pole at the origin, \( G(s) = \frac{1}{s^2} \), is not asymptotically stable by examining its impulse response.

Solution.

Using inverse Laplace,

\[ g(t) = \mathcal{L}^{-1}\left\{\frac{1}{s^2}\right\}(t) = t u(t). \]

The impulse response grows linearly with \( t \), so it is unbounded as \( t \rightarrow \infty \). Therefore the system is unstable (certainly not asymptotically stable). This is consistent with the theory: a repeated pole on the imaginary axis (\( \Re(p) = 0 \), multiplicity 2) yields polynomially growing terms \( t^{m-1} \).

Problem 4 (Eigenvalue-Based Test).

Consider the state matrix

\[ A = \begin{bmatrix} 0 & 1 & 0 \\ -4 & -5 & 0 \\ 0 & 0 & -2 \end{bmatrix}. \]

(a) Compute the eigenvalues of \( A \). (b) Classify the stability. (c) Interpret the third state in terms of decoupled dynamics.

Solution.

The upper-left \( 2 \times 2 \) block is

\[ A_{2\times 2} = \begin{bmatrix} 0 & 1 \\ -4 & -5 \end{bmatrix}. \]

Its characteristic polynomial is

\[ \det(sI - A_{2\times 2}) = s^2 + 5 s + 4 = 0, \]

which factors as \( (s+1)(s+4) = 0 \), giving eigenvalues \( \lambda_1 = -1 \) and \( \lambda_2 = -4 \). The third diagonal element of \( A \) is \( -2 \), so the third eigenvalue is \( \lambda_3 = -2 \).

All eigenvalues have negative real parts, so the system is asymptotically stable. The third state is completely decoupled (its dynamics are \( \dot{x}_3 = -2 x_3 \)), representing an independent exponentially decaying mode.

Problem 5 (Robotic Joint with Gravity Linearization).

A single-link robotic arm rotating in a vertical plane has nonlinear dynamics including a gravity term proportional to \( \sin(\theta) \). Linearizing around the upright equilibrium \( \theta = 0 \) yields (after feedback) a second-order characteristic polynomial

\[ s^2 + 2 \zeta \omega_n s + \omega_n^2 = 0. \]

(a) Express the poles in terms of \( \zeta \) and \( \omega_n \). (b) For which values of \( \zeta \) is the linearized system asymptotically stable?

Solution.

(a) The roots are

\[ s = -\zeta \omega_n \pm j \omega_n \sqrt{1 - \zeta^2}. \]

(b) The real part is \( -\zeta \omega_n \). Assuming \( \omega_n > 0 \), asymptotic stability requires \( \zeta > 0 \). The value of \( \zeta \) determines whether the system is underdamped, critically damped, or overdamped, but as long as \( \zeta > 0 \), both poles lie in the left half-plane and the equilibrium is asymptotically stable in the linear approximation.

13. Summary

In this lesson we established that asymptotic stability of an LTI system is completely determined by the locations of its poles (or equivalently, the eigenvalues of its state matrix). Using partial fraction expansions and the matrix exponential, we showed that exponential decay occurs if and only if all poles lie strictly in the open left half-plane. We distinguished asymptotic, marginal, and unstable configurations and illustrated how to implement stability checks in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica, including simple robot joint models. These pole-based tests form the foundation for algebraic criteria (Routh–Hurwitz) and graphical methods (root locus) to be developed in subsequent lessons.

14. References

  1. Routh, E.J. (1877). A Treatise on the Stability of a Given State of Motion. Macmillan, London.
  2. Hurwitz, A. (1895). Ueber die Bedingungen, unter welchen eine Gleichung nur Wurzeln mit negativen reellen Teilen besitzt. Mathematische Annalen, 46(2), 273–284.
  3. Lyapunov, A.M. (1892). Problème général de la stabilité du mouvement. (Russian original, French translation 1907).
  4. Kalman, R.E. (1960). Contributions to the theory of optimal control. Bol. Soc. Mat. Mexicana, 5(2), 102–119.
  5. Hille, E., & Phillips, R.S. (1957). Functional Analysis and Semi-Groups. American Mathematical Society.
  6. Zames, G. (1966). On the input–output stability of time-varying nonlinear feedback systems. IEEE Transactions on Automatic Control, 11(2), 228–238.
  7. Desoer, C.A., & Vidyasagar, M. (1975). Feedback Systems: Input–Output Properties. Academic Press.
  8. Wonham, W.M. (1967). On pole assignment in multi-input controllable linear systems. IEEE Transactions on Automatic Control, 12(6), 660–665.
  9. Kailath, T. (1971). Linear Systems. Prentice Hall.
  10. Rugh, W.J. (1996). Linear System Theory (2nd ed.). Prentice Hall.