For model predictive control (and other applications), it is common to calculate a quadratic function as follows.
quad_cost {n, p, N} -- For a horizon of N
(P :: double[n, n]) -- Terminal cost
(Q :: double[n, n]) -- Stage cost
(R :: double[p, p]) -- Controller cost
(x :: double[n, N]) -- N state vectors
(u :: double[p, N-1]) -- (N-1) control vectors
:: double
:= ( x[:, N]^T*P*x[:, N] +
sum (vec k in N-1 -> x[:, k]^T*Q*x[:, k] + u[:, k]^T*R*u[:,k]);
)[0];
In many cases, since we are not changing the matrices used in the quadratic function (either the matrices do not need to change or can't anyway because doing so would require a recompile), it is convenient to make functions where some of the inputs are prefilled in.
However, this version results in more assembly instructions (using gcc -O2) than the following, where the inlined data has been placed inside the quadratic function itself (loops can be unrolled, stack size can be constant, etc).
quad_cost2 -- For a horizon of 2
(x :: double[2, 2])
(u :: double[2, 1]) :: double
:= (
P := (mat (1, 0; 0, 1));
Q := (mat (1, 0; 0, 1));
R := (mat (1, 0; 0, 1));
N := 2;
x[:, N]^T*P*x[:, N] +
sum (vec k in N-1 -> x[:, k]^T*Q*x[:, k] + u[:, k]^T*R*u[:,k]);
)[0];
When converted into assembly, quad_cost2 has 5x fewer instructions than quad_cost and it is possible to get rid of the loops.
It would be convenient if Plover had a way of simplifying any functions where some of the fields already contain constant data to help the C compiler later make more optimized versions of the code.
This could also probably be done if an inline tag existed that could be passed into the C code.
For model predictive control (and other applications), it is common to calculate a quadratic function as follows.
In many cases, since we are not changing the matrices used in the quadratic function (either the matrices do not need to change or can't anyway because doing so would require a recompile), it is convenient to make functions where some of the inputs are prefilled in.
However, this version results in more assembly instructions (using gcc -O2) than the following, where the inlined data has been placed inside the quadratic function itself (loops can be unrolled, stack size can be constant, etc).
When converted into assembly,
quad_cost2
has 5x fewer instructions thanquad_cost
and it is possible to get rid of the loops.It would be convenient if Plover had a way of simplifying any functions where some of the fields already contain constant data to help the C compiler later make more optimized versions of the code.
This could also probably be done if an inline tag existed that could be passed into the C code.