PLACE

Pole placement (or full-state feedback gain design) calculates a gain matrix K such that the closed-loop system dynamics A - BK have a desired set of eigenvalues (poles).

This method is used when you want absolute control over the location of the system’s poles to achieve specific response characteristics like damping and settling time, provided the system is controllable.

Excel Usage

=PLACE(A, B, poles)
  • A (list[list], required): The state dynamics matrix A (NxN).
  • B (list[list], required): The input matrix B (NxM).
  • poles (list[list], required): The desired closed-loop pole locations (1xN or Nx1).

Returns (list[list]): The state feedback gain matrix K.

Example 1: Double integrator pole placement

Inputs:

A B poles
0 1 0 -2 -5
0 0 1

Excel formula:

=PLACE({0,1;0,0}, {0;1}, {-2,-5})

Expected output:

Result
10 7
Example 2: Accept flat list for desired poles

Inputs:

A B poles
0 1 0 -3,-6
0 0 1

Excel formula:

=PLACE({0,1;0,0}, {0;1}, -3,-6)

Expected output:

Result
18 9
Example 3: Place poles for damped model

Inputs:

A B poles
0 1 0 -4 -5
-2 -1 1

Excel formula:

=PLACE({0,1;-2,-1}, {0;1}, {-4,-5})

Expected output:

Result
18 8
Example 4: Place farther-left poles for faster response

Inputs:

A B poles
0 1 0 -6 -7
-1 -2 1

Excel formula:

=PLACE({0,1;-1,-2}, {0;1}, {-6,-7})

Expected output:

Result
41 11

Python Code

Show Code
import control as ct
import numpy as np

def place(A, B, poles):
    """
    Pole placement for state feedback gain design.

    See: https://python-control.readthedocs.io/en/latest/generated/control.place.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        A (list[list]): The state dynamics matrix A (NxN).
        B (list[list]): The input matrix B (NxM).
        poles (list[list]): The desired closed-loop pole locations (1xN or Nx1).

    Returns:
        list[list]: The state feedback gain matrix K.
    """
    try:
        def to_np(x):
            if x is None:
                return None
            if not isinstance(x, list):
                return np.array([[float(x)]])
            if len(x) > 0 and not isinstance(x[0], list):
                x = [x]
            return np.array([[float(v) if v is not None and str(v) != "" else 0.0 for v in row] for row in x])

        def parse_poles(x):
            values = []
            if not isinstance(x, list):
                x = [x]
            for item in x:
                if isinstance(item, list):
                    for v in item:
                        if v is not None and str(v) != "":
                            s = str(v)
                            values.append(complex(s.replace('i', 'j')) if 'i' in s or 'j' in s else float(v))
                elif item is not None and str(item) != "":
                    s = str(item)
                    values.append(complex(s.replace('i', 'j')) if 'i' in s or 'j' in s else float(item))
            return values

        a_np = to_np(A)
        b_np = to_np(B)
        p_list = parse_poles(poles)

        if len(p_list) == 0:
            return "Error: poles must contain at least one value"

        K = ct.place(a_np, b_np, p_list)

        return K.tolist()
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

The state dynamics matrix A (NxN).
The input matrix B (NxM).
The desired closed-loop pole locations (1xN or Nx1).