This week I refactored the `Linearizer`

class to fit a general system of
equations. This means that any of the following can be absent, and the
linearization still is valid:

with

$$ \begin{array}[rl] \\q, \dot{q} & \in \mathbb{R}^n \\ u, \dot{u} & \in \mathbb{R}^o \\ r & \in \mathbb{R}^s \end{array} $$Note that vectors can be absent too. This means the system can be entirely $q$ or $u$ components. More on this later.

Much of the rest of the week was spent finishing up all methods related to the
`KanesMethod`

class. This was mostly cleaning up the code base, and fixing
all the tests in place for the previous `linearize`

method. As of this point,
the linearization routines accomplish everything that was in place before, but
in a more general and extensible way. This is all included in the
`LinearizerClass`

branch on my GitHub repo. There is a pull request on my own
master branch open right now for code review
here. I'll leave this up for another
day or two before closing it and making all pull request to `Sympy/master`

.

I also started work on linearizing a system of equations presented in matrix form. This still needs lots of code improvements (it's inefficient), but it currently works. Below is a demo.

The system is the same system I use for my research - a dual solenoid actuator.
There are two dependent variables: `lam1`

and `lam2`

. The dynamics are thus
expressed by 3 dynamic differential equations, and two constraint equations.

In [1]:

```
from sympy import symbols, Matrix
from sympy.physics.mechanics import dynamicsymbols, mprint
from sympy.physics.mechanics.linearize import Linearizer, matrix_to_linearizer
# Create constant symbols
B1, B2 = symbols('B1, B2')
d1, d2, D = symbols('d1, d2, D')
R1, R2 = symbols('R1, R2')
m = symbols('m')
t = symbols('t')
# Create dynamicsymbols
i1, i2 = dynamicsymbols('i1, i2')
V1, V2 = dynamicsymbols('V1, V2')
x = dynamicsymbols('x')
xdot = x.diff()
lam1, lam2 = dynamicsymbols('lam1, lam2')
lam1dot, lam2dot = dynamicsymbols('lam1, lam2', 1)
# Define vectors. Because all speeds are derivatives of the coordinates,
# the system is best represented as just a vector of u. The dependent
# states are lam1 and lam2
u = Matrix([i1, i2, xdot, x, lam1, lam2])
udep = u[4:]
# Define system of equations
eom = Matrix([B1/(d1 + x)*i1 - lam1,
B2/(D + d2 - x)*i2 - lam2,
-lam1dot - R1*i1 + V1,
-lam2dot - R2*i2 + V2,
-xdot.diff() + (B2/(d2 + D - x)**2 * i2**2 - B1/(d1 + x)**2 * i1**2)/m])
# Perform the linearization
linearizer = matrix_to_linearizer(eom, u=u, udep=udep)
A, B = linearizer.linearize(A_and_B=True)
```

In [2]:

```
mprint(A)
```

In [3]:

```
mprint(B)
```

You'll have to trust me that the above representations are the same ones that I derived for my research project. This is really exciting progress! If everything works out (and it looks like it will), it will be possible to derive a system of dynamic equations anywhere in sympy, and then linearize it using the functionality I implement in the `linearize`

function.

Currently the system of equations is must formed as a matrix, and then passed
to `matrix_to_linearizer`

to return a `Linearizer`

object. Once this code is
cleaned up, it will be used internally by the general `linearize`

function to
convert the system to a `Linearizer`

, perform the linearization, and return
the results. I plan on implementing this functionality next week.

The code used above is found in my `matrix2linearizer`

branch on GitHub here. As before, I made a pull request on my own rep, so people may review the code before i submit it to Sympy proper. The PR is here.

comments powered by Disqus

All content copyright 2014-2017 Jim Crist unless otherwise noted. Licensed under Creative Commons.

Find me on Twitter, GitHub, Speaker Deck, or shoot me an email.