Symbolic framework
We can define scalar symbolic variables as follows
from gradgen import SX
x = SX.sym("x")
for vectors, use SXVector. For example, to create a vector of dimensions 2 do
from gradgen import SXVector
x = SXVector.sym("x", 2)
If you print x you will see
SXVector(elements=(SX.sym('x_0'), SX.sym('x_1')))
Details
Although SXVectors of length 1 behave like scalar, you can "cast"
an SXVector of length 1 as an SX using
x = SXVector.sym("x", 2)
x = x[0]
Lastly, note that x[a:b] returns an SXVector view.
n = 10
x = SXVector.sym("x", n)
x_slice = x[1:4] # <-- this is (x[1], x[2], x[3])
Symbolic expressions
Using scalar and vector symbols we can construct symbolic expressions. For example, to define the function $f(x) = ux/\Vert x \Vert_1$ we can do
f = u * x / x.norm1()
Several operations are supported. Indicatively, we support the operators **;
to define the expression $f = 1 + 0.1 z - 4 z^3$ we can write
z = SX.sym("u")
f = 1 + 0.1 * z - 4 * z**3
The operator **, when applied to vectors (SXVector), operates element-wise.
All trigonometric (cos, sin, tan),
inverse trigonometric (acos, asin, atan) and hyperbolic operations
(cosh, sinh, tanh) and their inverses (acosh, asinh, atanh) are
supported.
For vectors, the following scalar-valued operations are available:
norm2(): Euclidean normnorm2sq(): squared Euclidean normnorm1(): norm-1norm_inf(): Infinity normnorm_p(p): $p$-normnorm_p_to_p(p): $p$-norm to the power $p$
In optimal control applications we frequently encounter terms of the form
$x^\intercal P x$, where $P$ is a symmetric matrix. Such expressions can be
constructed with quadform as follows
import gradgen as gg
x = SXVector.sym("x", 2)
P = [[1, 4],
[4, 5]]
f = gg.quadform(P, x, is_symmetric=True)
If is_symmetric=True is used, then a simpler expression is generated,
however, an exception is raised if the provided matrix P is not truly
symmetric.
One limitation of the current framework is that $P$ needs to be a constant matrix. Quadratic forms with a symbolic matrix will be supported in a future version.
Likewise, we often need to compute dot products. This can be done with dot:
n = 3
x = SXVector.sym("x", n)
q = SXVector.sym("x", n)
f = x.dot(q)