Lie operators for vector fields¶
In order to compute the normal form of an equation \(\dot{x}=f(x)\), the normal_forms.normal_form.normal_form
class solves a sequence of equations \(L_1g_j=f_j-h_j\) and applies a sequence of transformations \(e^{L_j}\) to the \(k\)-jet of \(f\), where \(L_1(\cdot)=[\cdot,f_1(x)]\) and \(L_j(\cdot)=[\cdot,g_j(x)]\) are the Lie brackets with particular homogenous polynomial vector fields \(f_1(x)=f'(x_0)x\) or \(g_j(x)\). This package uses the Lie bracket for vector fields definition \([f(x),g(x)]=f'(x)g(x)-g'(x)f(x)\). The class that implements the Lie bracket with a particular polynomial vector field is normal_forms.lie_operator.lie_operator
.
Let \(\mathcal{V}^n_i\) denote the space of \(n\)-dim, degree \(i\) polynomial vector fields, and let \(s(i)\) denote the simplicial number \({n+i-1 \choose i}\). For any degree \(i\), the vector field \(f_i\in\mathcal{V}_i^n\) may be represented as a \(ns(i)\)-dim column vector, the operator \(L_j:\mathcal{V}_i^n\rightarrow\mathcal{V}_{i+j-1}^n\) defined by \(L_j=[\cdot,g_j(x)]\) may be represented as a \(ns(i+j-1)\times ns(i)\) matrix, and \(L_j(f_i)\) may be represented as the matrix-vector product.
These representations depend on the choice of basis for \(\mathcal{V}^n\). This package implements a basis for \(\mathcal{V}_i^n\) ordered first by coordinate then by multiindex. For example, the basis for \(\mathcal{V}^2_3\) is
The underlying list of multiindices, \((3,0), (2,1), (1,2), (0,3)\) in the example, assumes a descending order according to a dictionary ordering, i.e.for two multiindices \(m=(m_1,\ldots,m_n)\) and \(p=(p_1,\ldots,p_n)\), \(m>p\) if \(m_i=p_i\) and \(m_j>p_j\), for all \(i\) and a particular \(j\) such that \(0\leq i<j\leq n\).
For example, a vector field
in \(\mathcal{V}_3^2\) is represented as the column vector \(\begin{bmatrix}c_{11}&c_{12}&c_{13}&c_{14}&c_{21}&c_{22}&c_{23}&c_{24}\end{bmatrix}^T\).
And, the columns of the matrix representation of \(L_j:\mathcal{V}_i^n\rightarrow\mathcal{V}_{i+j-1}^n\) are the column vector representations of \(L_j\) applied to the basis of \(\mathcal{V}_i^n\). For example, let \(g_2(x_1,x_2)=\begin{bmatrix}x_1^2\\x_2^2\end{bmatrix}\) and consider \(L_2:\mathcal{V}_3^2\rightarrow\mathcal{V}_4^2\) defined by \(L_2(\cdot)=[\cdot,g_2(x)]\). Since
the first column of the matrix representation of \(L_2:\mathcal{V}_3^2\rightarrow\mathcal{V}_4^2\) is \(\begin{bmatrix}1&0&0&0&0 & 0&0&0&0&0\end{bmatrix}^T\).
Finally, \(L_j(f_i)\) is represented as a column vector computed by the appropriate matrix representation of \(L_j\) times the column vector representation of \(f_i\).
The normal_forms.lie_operator.lie_operator
class is accessible from the top-level of this package. To create a lie_operator
object, a vector field g
as a sympy.Matrix
and a list of sympy.symbols
representing the variables \(x_1,\ldots,x_n\) should be supplied. Once the lie_operator
object is constructed, the matrix representation of its action on \(\mathcal{V}_j^n\) can be accessed as index j
of the object.
In [1]: from normal_forms import lie_operator
In [2]: import sympy
In [3]: x = sympy.symbols('x_1 x_2')
In [4]: g2 = sympy.Matrix([[x[0]**2],[x[1]**2]])
In [5]: L2 = lie_operator(g2, x)
In [6]: L2[3]
Out[6]:
array([[ 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 1., -1., 0., 0., 0., 0., 0.],
[ 0., 0., 2., -2., 0., 0., 0., 0.],
[ 0., 0., 0., 3., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 3., 0., 0., 0.],
[ 0., 0., 0., 0., -2., 2., 0., 0.],
[ 0., 0., 0., 0., 0., -1., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 1.]])
The lie_operator
object can be evaluated by passing it a vector field in the form of a sympy.Matrix
as an argument:
In [7]: f3 = sympy.Matrix([[x[0]**3],[0]])
In [8]: L2(f3)
Out[8]:
Matrix([
[1.0*x_1**4],
[ 0]])