- SOFOpt_MATLAB
This repository provides a MATLAB interface for the SOFOpt engine. The interface, currently, has been teston on MATLAB under Windows and Linux.
SOFOpt is aimed at solving structured continuous-time static output feedback LQR problems. Given the continuous-time system
with measured output
the goal is to compute a static output feedback gain (K_y) such that
Equivalently, the closed-loop state feedback matrix is
The optimization problem is to minimize the infinite-horizon quadratic cost
for a given initial condition (x(0) = x_0), possibly subject to a prescribed sparsity structure on (K_y).
A structured static output feedback constraint has the form
Since static output feedback optimization is generally nonconvex and NP-hard, SOFOpt does not guarantee the global optimum for every problem instance. Instead, it tries to compute a practical stabilizing solution by using the full-state LQR solution as a reference and starting point for the nonlinear optimization process.
More details on the numerical method and the C++ engine can be found in the SOFOpt README.
The MATLAB interface provides two main functions:
SOFOpt()
SOFOptimoptions()Static output feedback optimization for continuous-time systems.
optim_out = SOFOpt(A,B,C,Q,R,X0)
optim_out = SOFOpt(A,B,C,Q,R,X0,structure)
optim_out = SOFOpt(A,B,C,Q,R,X0,opt)
optim_out = SOFOpt(A,B,C,Q,R,X0,structure,opt)optim_out = SOFOpt(A,B,C,Q,R,X0)solves the continuous-time static output feedback LQR problem using the default optimization options.
The matrices must define the system
dx/dt = A*x + B*u
y = C*x
u = -Ky*ywhere Ky is the static output feedback gain optimized by SOFOpt.
optim_out = SOFOpt(A,B,C,Q,R,X0,structure)imposes a sparsity pattern on Ky.
The matrix structure must be a logical matrix with the same size as Ky. Entries equal to false are fixed to zero, while entries equal to true are optimized.
Equivalently,
and
optim_out = SOFOpt(A,B,C,Q,R,X0,opt)uses the optimization options specified by opt.
The options structure can be created with
opt = SOFOptimoptions();and then modified before calling SOFOpt.
optim_out = SOFOpt(A,B,C,Q,R,X0,structure,opt)uses both a prescribed sparsity structure and user-defined optimization options.
The returned structure optim_out contains the following fields:
| Field | Description |
|---|---|
Ky |
Optimized static output feedback gain. |
Kx |
Equivalent state feedback gain, with Kx = Ky*C. |
LQR_cost |
Cost J(X0) obtained with full-state LQR. |
Output_cost |
Cost J(X0) obtained with static output feedback. |
Result |
Optimization result string returned by NLopt. |
Creates an options structure for SOFOpt.
opt = SOFOptimoptions()opt.use_P_precond = true;
opt.rho_alpha = 0.1;
opt.beta = 100;
opt.r = 1e-5;
opt.c = 500;| Field | Default | Description |
|---|---|---|
use_P_precond |
true |
If enabled, the full-state LQR Riccati matrix P is used as an internal state-space preconditioner. This can improve numerical conditioning when the states have different scales or physical units. The returned gains are always expressed in the original coordinates. |
rho_alpha |
0.1 |
Spectral-abscissa safety ratio. It defines the required closed-loop stability margin relative to the full-state LQR closed loop. Smaller values relax the required decay rate; values closer to 1 require a margin closer to the full-state LQR one. |
beta |
100 |
Softmax smoothing parameter for the spectral abscissa. Larger values give a closer approximation to max(real(eig(Acl))), while smaller values give a smoother but less accurate approximation. |
r |
1e-5 |
Relative safety shift used in the smoothed performance index. It affects where the smooth cost extension starts penalizing unsafe or high-cost regions. |
c |
500 |
Smoothing ratio for the performance index. It controls the sharpness of the transition in the smooth cost extension near unstable or numerically critical regions. |
The default values are intended as a robust starting point.
The most relevant tuning parameter is usually rho_alpha, because it directly changes the requested stability margin. A smaller rho_alpha generally makes the optimization easier, while a larger value asks for a faster closed-loop decay rate and may increase the cost.
The parameters beta, r, and c mainly affect numerical smoothing and convergence. They can be tuned when the optimizer has difficulty converging, when the spectral-abscissa constraint is active, or when the closed-loop system is close to instability.
Using
opt.use_P_precond = true;is usually recommended.
SOFOpt can be called from MATLAB in two different ways:
- through an external executable;
- through a directly linked dynamic library.
By default, this interface calls the SOFOpt engine through the executable gateway SOFOpt_exec.mex.
This choice is intentional. MATLAB loads its own runtime libraries, including BLAS and LAPACK-related libraries. These can conflict with the numerical libraries required by SOFOpt and its dependencies. Calling the external executable isolates the SOFOpt runtime from the MATLAB runtime and is therefore the recommended and more portable approach.
The repository also includes SOFOpt_mex.mex, which calls the SOFOpt dynamic library directly. This mode can be faster and more direct, but it is more sensitive to library conflicts and usually requires more careful build and linking strategies. For this reason, the executable interface is recommended for standard use.
The repository includes examples and benchmark problems showing the behavior of SOFOpt on structured static output feedback problems.
| Example | Description |
|---|---|
COMPleib_AC1 |
AC1 benchmark from COMPleib. Also compared with the HIFOO result reported in Some control design experiments with hifoo. |
COMPleib_AC10 |
AC10 benchmark from COMPleib. |
COMPleibLIKE_tg1 |
Test problem inspired by the COMPleib TG1 benchmark. |
LeaderFollower |
Multi-agent predecessor-following example. |
RoomTemperature |
Room-temperature regulation with limited state measurements. |
SpringDumpers_x25 |
Chain of 25 spring-damper systems controlled with 5 inputs and 10 measured outputs. |
The table reports the full-state LQR reference cost, the SOFOpt cost, the relative cost increase, and the closed-loop spectral abscissa.
For continuous-time systems, the closed loop is stable when the spectral abscissa is negative.
| Example | LQR cost | SOFOpt cost | Cost ratio | Cost increase | LQR alpha | SOFOpt alpha | rho_alpha | Alpha bound |
|---|---|---|---|---|---|---|---|---|
COMPleib_AC1 |
13.4735 | 14.3290 | 1.0635 | 6.35 % | -0.5621 | -0.2845 | 0.5 | -0.2810 |
COMPleib_AC10 |
11856.8723 | 18115909.26 | 1527.8826 | 152688.26 % | -0.08677 | -0.02844 | 0.2 | -0.01735 |
COMPleibLIKE_tg1 |
6.7670 | 10.5829 | 1.5639 | 56.39 % | -0.1562 | -0.05496 | 0.2 | -0.03124 |
LeaderFollower |
6021674.93 | 6108327.78 | 1.0144 | 1.44 % | -8.595e-05 | -0.01678 | - | - |
RoomTemperature |
14.2695 | 14.2707 | 1.0001 | 0.008 % | -0.1048 | -0.05252 | - | - |
SpringDumpers_x25 |
6.5927 | 7.9495 | 1.2058 | 20.58 % | -0.08135 | -0.06245 | 0.5 | -0.04068 |
For the COMPleib_AC1 benchmark, the SOFOpt result is compared with the static output feedback controller reported in the HIFOO experiment note Some control design experiments with hifoo.
| Method | Cost | Cost ratio | Spectral abscissa | Notes |
|---|---|---|---|---|
| Full-state LQR | 13.4735 | 1.0000 | -0.5621 | Reference full-state controller. |
| HIFOO SOF reference | - | - | -0.07959 | Static output feedback controller reported in the HIFOO paper. |
| SOFOpt SOF | 14.3290 | 1.0635 | -0.2845 | Static output feedback obtained by SOFOpt with rho_alpha = 0.5. |
In this benchmark, SOFOpt obtains a static output feedback solution with a larger stability margin than the HIFOO controller reported in the paper. The SOFOpt cost is about 6.35 % higher than the full-state LQR reference cost.
The AC1 figure also includes the state trajectories obtained using the HIFOO controller from the paper.
The COMPleibLIKE_tg1 example is inspired by the COMPleib TG1 benchmark.
SOFOpt finds a stabilizing static output feedback solution satisfying the requested spectral-abscissa constraint. The cost is higher than the full-state LQR reference, as expected for an output feedback controller using only measured outputs.
The RoomTemperature example shows a case where static output feedback closely matches the full-state LQR cost, despite using only limited measurements.
The SpringDumpers_x25 example considers a chain of 25 spring-damper systems with 5 control inputs and 10 measured outputs.
SOFOpt obtains a stabilizing static output feedback solution with about 20.58 % cost increase with respect to the full-state LQR reference.
The full-state LQR solution is used as a reference and as a numerical guide for the optimization. The static output feedback solution is generally expected to have a larger cost because it uses only
y = C*xinstead of the full state.
The COMPleib_AC10 benchmark is significantly harder than COMPleib_AC1. In this case, SOFOpt finds a stabilizing solution satisfying the requested spectral-abscissa constraint, but with a much larger cost than the full-state LQR reference.
The LeaderFollower example shows that SOFOpt can also improve the closed-loop decay rate in a multi-agent setting. In this case, the spectral abscissa moves from approximately -8.595e-05 to -0.01678, with only about 1.44 % cost increase.
Prebuilt binary packages are available from the GitHub Releases page for Windows and Linux.
This repository uses SOFOpt as a Git submodule. Therefore, the repository must be cloned together with its submodules:
git clone --recurse-submodules https://github.com/andrea993/SOFOpt_MATLAB
cd SOFOpt_MATLABIf the repository was already cloned without submodules, initialize them with:
git submodule update --init --recursiveBefore building the MATLAB interface, the SOFOpt C++ engine must be built.
Enter the SOFOpt submodule directory:
cd SOFOptOn Linux, build the engine with:
cmake --preset SOFOpt-Linux
cmake --build out/build/SOFOpt-LinuxOn Windows with MSVC, build the engine with:
cmake --preset SOFOpt-MSVC
cmake --build out/build/SOFOpt-MSVCFor additional build options, dependencies, and platform-specific details, see the SOFOpt README.
The MATLAB interface is built using mex, so MATLAB must be configured with a supported C compiler.
From the MATLAB command window, run:
mex -setup cOn Linux, this usually selects gcc. On Windows, this usually requires a supported Microsoft Visual Studio / MSVC compiler installation.
From the root directory of this repository, run in MATLAB:
SOFOpt_Build()The build script compiles the MATLAB MEX gateways and configures the path to the SOFOpt executable.
On Linux, it expects the SOFOpt engine to have been built in:
SOFOpt/out/build/SOFOpt-Linux
and uses:
SOFOpt/out/build/SOFOpt-Linux/bin/solver_exec
SOFOpt/out/build/SOFOpt-Linux/lib/
On Windows, it expects the SOFOpt engine to have been built in:
SOFOpt/out/build/SOFOpt-MSVC
and uses:
SOFOpt/out/build/SOFOpt-MSVC/bin/solver_exec.exe
SOFOpt/out/build/SOFOpt-MSVC/lib/SOFOpt_Lib.lib
The build generates two MATLAB gateways:
| File | Description |
|---|---|
SOFOpt_exec.mex* |
Recommended interface. It calls the SOFOpt solver through the external executable. |
SOFOpt_mex.mex* |
Direct dynamic-library interface. It links directly against SOFOpt_Lib. |
The executable interface is the recommended one because it isolates the SOFOpt runtime from the MATLAB runtime. This is useful because MATLAB can load its own numerical libraries, such as BLAS and LAPACK implementations, which may conflict with the libraries used by SOFOpt.