```python
#import krotov
#import qutip as qt# NBVAL_IGNORE_OUTPUT
#import qutip
#import numpy as np
#import scipy
#import matplotlib
#import matplotlib.pylab as plt
#import krotov
import numpy as np
import sympy as sp
from sympy import Function,Symbol,symbols,zeros,Matrix,sqrt,simplify,solve,diff,dsolve,lambdify
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from sympy.physics.quantum.dagger import Dagger
```

```python
t=Symbol('t')
gamma=Symbol('gamma',Real=True,positive=True)
Nb=Symbol('N_b',Real=True,positive=True)
x = Function('x')(t)
c= Function('c')(t)
x1 = Function('x1')(t)
x2 = Function('x2')(t)
p1= Function('p1')(t)
p2 = Function('p2')(t)
e=Function('e')(t)
mu,g=symbols('mu g')
x11,x12,p11,p12,e1,de1,c1=symbols('x1 x2 p1 p2 e de c')
de=diff(e,t)
F=zeros(2,2)
F[0,1]=1
F[1,0]=-1
B=zeros(2,2)
B[0,0]=1
B[1,1]=-1
#A=np.block([
 #       [g*B+F,             Matrix([[0,0],[0,0]])],
  #      [Matrix([[0,0],[0,0]]), g*B  +F             ]
   #     ])
Omega=sp.Matrix([[0,0,0,0,0],[0,0,0,1,0],[0,0,0,0,1],[0,-1,0,0,0],[0,0,-1,0,0]])
G=sp.Matrix([[0,0,0,0,0],[0,1+2*mu*e,g,0,0],[0,g,1,0,0],[0,0,0,1-2*mu*e,g],[0,0,0,g,1]])
C=sp.Matrix([[0,0,0,0,0],[0,sp.sqrt(gamma*(Nb+1)/2),0,1j*sp.sqrt(gamma*(Nb+1)/2),0],[0,sp.sqrt(gamma*(Nb)/2),0,-1j*sp.sqrt(gamma*(Nb)/2),0],[0,0,0,0,0],[0,0,0,0,0]])
A=Omega*G+Omega*((Dagger(C)*C).as_real_imag()[1])
D=Omega*((Dagger(C)*C).as_real_imag()[0])*Omega.T
d=[]
d.append(c)
d.append(0)
d.append(0)
d.append(0)
d.append(0)
v=[]
v.append(c)
v.append(x1)
v.append(x2)
v.append(p1)
v.append(p2)
```

```python
def to_symbols(expr):
    return expr.subs({x1:x11,x2:x12,p1:p11,p2:p12,e:e1,diff(e,t):de1,c:c1})
```

```python
v=Matrix(v)
to_symbols(v)
```

$\displaystyle \left[\begin{matrix}c\\x_{1}\\x_{2}\\p_{1}\\p_{2}\end{matrix}\right]$

```python
r=simplify(diff(v,t)-Matrix(A)*Matrix(v)-Matrix(Omega)*Matrix(d))
r
```

$\displaystyle \left[\begin{matrix}\frac{d}{d t} c{\left(t \right)}\\- g \operatorname{p_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{x_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{p_{1}}{\left(t \right)} + \frac{d}{d t} \operatorname{x_{1}}{\left(t \right)}\\- g \operatorname{p_{1}}{\left(t \right)} - \operatorname{p_{2}}{\left(t \right)} + \frac{d}{d t} \operatorname{x_{2}}{\left(t \right)}\\g \operatorname{x_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{p_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{x_{1}}{\left(t \right)} + \frac{d}{d t} \operatorname{p_{1}}{\left(t \right)}\\g \operatorname{x_{1}}{\left(t \right)} + \operatorname{x_{2}}{\left(t \right)} + \frac{d}{d t} \operatorname{p_{2}}{\left(t \right)}\end{matrix}\right]$

```python
vector=diff(Matrix([c,x1,x2,p1,p2]),t)
```

```python
import sympy
#eqs=list(to_symbols(Matrix(A)*Matrix(v)))
#t=sympy.linear_eq_to_matrix(eqs, [x11,x12,p11,p12,c1])[0]

```

```python
#t2=sympy.linear_eq_to_matrix(eqs, [x11,x12,p11,p12,c1])[1]
```

```python
#t*Matrix([x11,x12,p11,p12,c1])
```

```python
sol=simplify(r-diff(Matrix([c,x1,x2,p1,p2]),t))
sol
```

$\displaystyle \left[\begin{matrix}0\\- g \operatorname{p_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{x_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{p_{1}}{\left(t \right)}\\- g \operatorname{p_{1}}{\left(t \right)} - \operatorname{p_{2}}{\left(t \right)}\\g \operatorname{x_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{p_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{x_{1}}{\left(t \right)}\\g \operatorname{x_{1}}{\left(t \right)} + \operatorname{x_{2}}{\left(t \right)}\end{matrix}\right]$

```python
import sympy
eqs=list(to_symbols(sol))
t=sympy.linear_eq_to_matrix(eqs, [c1,x11,x12,p11,p12])[0]
t2=sympy.linear_eq_to_matrix(eqs, [c1,x11,x12,p11,p12])[1]

```

```python
t*Matrix([c1,x11,x12,p11,p12])+vector
```

$\displaystyle \left[\begin{matrix}\frac{d}{d t} c{\left(t \right)}\\- g p_{2} + 0.5 \gamma x_{1} + p_{1} \left(2 e \mu - 1\right) + \frac{d}{d t} \operatorname{x_{1}}{\left(t \right)}\\- g p_{1} - p_{2} + \frac{d}{d t} \operatorname{x_{2}}{\left(t \right)}\\g x_{2} + 0.5 \gamma p_{1} + x_{1} \left(2 e \mu + 1\right) + \frac{d}{d t} \operatorname{p_{1}}{\left(t \right)}\\g x_{1} + x_{2} + \frac{d}{d t} \operatorname{p_{2}}{\left(t \right)}\end{matrix}\right]$

```python
def to_func(expr):
    return expr.subs({x11:x1,x12:x2,p11:p1,p12:p2,e1:e,de1:de,c1:c})
```

```python
new_eqs=to_func(t*Matrix([c1,x11,x12,p11,p12])+vector)
new_eqs
```

$\displaystyle \left[\begin{matrix}\frac{d}{d t} c{\left(t \right)}\\- g \operatorname{p_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{x_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{p_{1}}{\left(t \right)} + \frac{d}{d t} \operatorname{x_{1}}{\left(t \right)}\\- g \operatorname{p_{1}}{\left(t \right)} - \operatorname{p_{2}}{\left(t \right)} + \frac{d}{d t} \operatorname{x_{2}}{\left(t \right)}\\g \operatorname{x_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{p_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{x_{1}}{\left(t \right)} + \frac{d}{d t} \operatorname{p_{1}}{\left(t \right)}\\g \operatorname{x_{1}}{\left(t \right)} + \operatorname{x_{2}}{\left(t \right)} + \frac{d}{d t} \operatorname{p_{2}}{\left(t \right)}\end{matrix}\right]$

```python
#field=np.linspace(0,100,1000)
lista=np.random.rand(5)
time,dt=np.linspace(1,10,5,retstep=True)
def field_discrete(lista,t,dt):
    return lista[int(t/dt)]

def derivative(lista,t,dt):
    return np.array([(lista[j]-lista[j-1])/(dt) if (j!=0)&(j!=len(lista)) else lista[j] for j in range(0,len(lista))])[int(t/dt)]
```

```python
lista
```

    array([0.18773669, 0.66300483, 0.99995879, 0.72723594, 0.38313259])

```python
derivative(lista,time[1],dt)
```

    0.21123028467962757

```python
(lista[1]-lista[0])/dt
```

    0.21123028467962757

```python
field_discrete(lista,10,dt)
```

    0.38313258597515254

```python
#sol=solve([r[0],r[1],r[2],r[3]],diff(x1,t),diff(x2,t),diff(p1,t),diff(p2,t))
#sol
```

```python
#d1=simplify(sol[diff(x1,t)])
#d2=simplify(sol[diff(x2,t)])
#d3=simplify(sol[diff(p1,t)])
#d4=simplify(sol[diff(p2,t)])

```

```python
#x1_diff(x1,x2,p1,p2,g,diff(e,t),e,mu)
```

```python
#p1_diff(x1,x2,p1,p2,g,diff(e,t),e,mu)
```

```python
#p2_diff(x1,x2,p1,p2,g,diff(e,t),e,mu)
```

```python
#x2_diff(x1,x2,p1,p2,g,diff(e,t),e,mu)
```

```python
#x1_diff=lambdify((x1,x2,p1,p2,g,diff(e,t),e,mu),d1)
#x2_diff=lambdify((x1,x2,p1,p2,g,diff(e,t),e,mu),d2)
#p1_diff=lambdify((x1,x2,p1,p2,g,diff(e,t),e,mu),d3)
#p2_diff=lambdify((x1,x2,p1,p2,g,diff(e,t),e,mu),d4)
```

```python
#x1_diff(x1,x2,g,diff(e,t),e,mu)
##def x1_diff(x1,x2,g,rec,e,mu):
 #   return  x1**2 #x1*x2*g*rec*e*mu
#def x2_diff(x1,x2,g,rec,e,mu):
 #   return  x2*g*rec**2 *e*mu#(x1)**2 + x2 *g*rec*e*mu
```

```python
#x2_diff(x1,x2,g,diff(e,t),e,mu)
```

```python
def vectorfield( t,w, p):
    """
    Defines the differential equations for  system.

    Arguments:
        w :  vector of the state variables:
                  w = [x1,x2]
        t :  time
        p: vector of parameters
            p=[g,field,dt,mu]
    """
    x1, x2,p1,p2 = w
    g,field,dt,mu=p
    # Create f = (x1',y1',x2',y2'):
    f = [x1_diff(x1,x2,p1,p2,g,derivative(field,t,dt),field_discrete(field,t,dt),mu),x2_diff(x1,x2,p1,p2,g,derivative(field,t,dt),field_discrete(field,t,dt),mu),
        p1_diff(x1,x2,p1,p2,g,derivative(field,t,dt),field_discrete(field,t,dt),mu),p2_diff(x1,x2,p1,p2,g,derivative(field,t,dt),field_discrete(field,t,dt),mu)]
    return f
```

```python
#from scipy.integrate import solve_ivp as ivp

#ini=0
#g=0.2
#fin=np.pi/g
#lt=1000
#ini_x1=0.05
#ini_x2=1
#field=np.random.rand(lt)
#np.loadtxt("EFieldValuesFINAL.txt")
#time=np.linspace(ini,fin,lt)
#field=guess_field(time,ini,fin,lt)
#dt=fin/(lt-1)
#p=[g,field,dt,0.1]
#wsol = ivp(vectorfield, [ini,fin],[ini_x1,ini_x1,10,10], args=(p,),t_eval=time)
```

```python
#wsol.message
```

```python
#%timeit wsol = ivp(vectorfield, [ini,fin],[ini_x1,ini_x2], args=(p,),t_eval=time)
```

```python
#from edos import guess_field

```

```python
#import matplotlib.pyplot as plt
#plt.figure(figsize=(18, 6), dpi=80)
#plt.plot(wsol.t,wsol.y[0],label=r'$x_{1}$')
#plt.plot(wsol.t,wsol.y[1],'-.',label=r'$x_{2}$')
#plt.plot(wsol.t,wsol.y[2],'-.',label=r'$p_{1}$')
#plt.plot(wsol.t,wsol.y[3],'-.',label=r'$p_{2}$')

#plt.legend()
#plt.show()
```

```python
#Now with CM Matrix
```

```python
t=Symbol('t')
v11 = Function('v11')(t)
v12 = Function('v12')(t)
v13= Function('v13')(t)
v14 = Function('v14')(t)
v22= Function('v22')(t)
v23 = Function('v23')(t)
v24= Function('v24')(t)
v33 = Function('v33')(t)
v34= Function('v34')(t)
v44 = Function('v44')(t)
x1 = Function('x1')(t)
x2 = Function('x2')(t)
p1= Function('p1')(t)
p2 = Function('p2')(t)
g= symbols('g')
e=Function('e')(t)
mu=symbols('mu')
Omega=sp.Matrix([[0,0,1,0],[0,0,0,1],[-1,0,0,0],[0,-1,0,0]])
G=sp.Matrix([[1+2*mu*e,g,0,0],[g,1,0,0],[0,0,1-2*mu*e,g],[0,0,g,1]])
C=sp.Matrix([[sp.sqrt(gamma*(Nb+1)/2),0,1j*sp.sqrt(gamma*(Nb+1)/2),0],[sp.sqrt(gamma*(Nb)/2),0,-1j*sp.sqrt(gamma*(Nb)/2),0],[0,0,0,0],[0,0,0,0]])
A=Omega*G+Omega*((Dagger(C)*C).as_real_imag()[1])
D=Omega*((Dagger(C)*C).as_real_imag()[0])*Omega.T
#V=Matrix([[v11-2*x1+alpha**2,v12-alpha*x2+beta*x1-alpha*beta,v13-alpha*p1,v14-alpha*p2],[v12-alpha*x2+beta*x1-alpha*beta,v22+beta**2+2*x2,v23+beta*p1,v24+beta*p2],[v13-alpha*p1,v23+beta*p1,v33,v34],[v14-alpha*p2,v24+beta*p2,v34,v44]])
V=Matrix([[v11,v12,v13,v14],[v12,v22,v23,v24],[v13,v23,v33,v34],[v14,v24,v34,v44]])

```

```python
V
```

$\displaystyle \left[\begin{matrix}\operatorname{v_{11}}{\left(t \right)} & \operatorname{v_{12}}{\left(t \right)} & \operatorname{v_{13}}{\left(t \right)} & \operatorname{v_{14}}{\left(t \right)}\\\operatorname{v_{12}}{\left(t \right)} & \operatorname{v_{22}}{\left(t \right)} & \operatorname{v_{23}}{\left(t \right)} & \operatorname{v_{24}}{\left(t \right)}\\\operatorname{v_{13}}{\left(t \right)} & \operatorname{v_{23}}{\left(t \right)} & \operatorname{v_{33}}{\left(t \right)} & \operatorname{v_{34}}{\left(t \right)}\\\operatorname{v_{14}}{\left(t \right)} & \operatorname{v_{24}}{\left(t \right)} & \operatorname{v_{34}}{\left(t \right)} & \operatorname{v_{44}}{\left(t \right)}\end{matrix}\right]$

```python
r=simplify(diff(V,t)-Matrix(A)*Matrix(V)-Matrix(V)*Matrix(A).T-D)
simplify(r)
```

$\displaystyle \left[\begin{matrix}- 1.0 N_{b} \gamma - 2 g \operatorname{v_{14}}{\left(t \right)} + 1.0 \gamma \operatorname{v_{11}}{\left(t \right)} - 0.5 \gamma + 4 \mu e{\left(t \right)} \operatorname{v_{13}}{\left(t \right)} - 2 \operatorname{v_{13}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{11}}{\left(t \right)} & - g \operatorname{v_{13}}{\left(t \right)} - g \operatorname{v_{24}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{12}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{v_{23}}{\left(t \right)} - \operatorname{v_{14}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{12}}{\left(t \right)} & g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} + 1.0 \gamma \operatorname{v_{13}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{v_{33}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{v_{11}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{13}}{\left(t \right)} & g \operatorname{v_{11}}{\left(t \right)} - g \operatorname{v_{44}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{14}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{v_{34}}{\left(t \right)} + \operatorname{v_{12}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{14}}{\left(t \right)}\\- g \operatorname{v_{13}}{\left(t \right)} - g \operatorname{v_{24}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{12}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{v_{23}}{\left(t \right)} - \operatorname{v_{14}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{12}}{\left(t \right)} & - 2 g \operatorname{v_{23}}{\left(t \right)} - 2 \operatorname{v_{24}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{22}}{\left(t \right)} & g \operatorname{v_{22}}{\left(t \right)} - g \operatorname{v_{33}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{23}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{v_{12}}{\left(t \right)} - \operatorname{v_{34}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{23}}{\left(t \right)} & g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} + \operatorname{v_{22}}{\left(t \right)} - \operatorname{v_{44}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{24}}{\left(t \right)}\\g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} + 1.0 \gamma \operatorname{v_{13}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{v_{33}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{v_{11}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{13}}{\left(t \right)} & g \operatorname{v_{22}}{\left(t \right)} - g \operatorname{v_{33}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{23}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{v_{12}}{\left(t \right)} - \operatorname{v_{34}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{23}}{\left(t \right)} & - N_{b} \gamma + 2 g \operatorname{v_{23}}{\left(t \right)} + \gamma \operatorname{v_{33}}{\left(t \right)} - \frac{\gamma}{2} + 4 \mu e{\left(t \right)} \operatorname{v_{13}}{\left(t \right)} + 2 \operatorname{v_{13}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{33}}{\left(t \right)} & g \operatorname{v_{13}}{\left(t \right)} + g \operatorname{v_{24}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{34}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{v_{14}}{\left(t \right)} + \operatorname{v_{23}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{34}}{\left(t \right)}\\g \operatorname{v_{11}}{\left(t \right)} - g \operatorname{v_{44}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{14}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{v_{34}}{\left(t \right)} + \operatorname{v_{12}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{14}}{\left(t \right)} & g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} + \operatorname{v_{22}}{\left(t \right)} - \operatorname{v_{44}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{24}}{\left(t \right)} & g \operatorname{v_{13}}{\left(t \right)} + g \operatorname{v_{24}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{34}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{v_{14}}{\left(t \right)} + \operatorname{v_{23}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{34}}{\left(t \right)} & 2 g \operatorname{v_{14}}{\left(t \right)} + 2 \operatorname{v_{24}}{\left(t \right)} + \frac{d}{d t} \operatorname{v_{44}}{\left(t \right)}\end{matrix}\right]$

```python
new_eqs
```

$\displaystyle \left[\begin{matrix}\frac{d}{d t} c{\left(t \right)}\\- g \operatorname{p_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{x_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{p_{1}}{\left(t \right)} + \frac{d}{d t} \operatorname{x_{1}}{\left(t \right)}\\- g \operatorname{p_{1}}{\left(t \right)} - \operatorname{p_{2}}{\left(t \right)} + \frac{d}{d t} \operatorname{x_{2}}{\left(t \right)}\\g \operatorname{x_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{p_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{x_{1}}{\left(t \right)} + \frac{d}{d t} \operatorname{p_{1}}{\left(t \right)}\\g \operatorname{x_{1}}{\left(t \right)} + \operatorname{x_{2}}{\left(t \right)} + \frac{d}{d t} \operatorname{p_{2}}{\left(t \right)}\end{matrix}\right]$

```python
c_eqs=[r[0,0],r[0,1],r[0,2],r[0,3],r[1,1],r[1,2],r[1,3],r[2,2],r[2,3],r[3,3]]
```

```python
gaga=new_eqs-vector
gaga
```

$\displaystyle \left[\begin{matrix}0\\- g \operatorname{p_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{x_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} - 1\right) \operatorname{p_{1}}{\left(t \right)}\\- g \operatorname{p_{1}}{\left(t \right)} - \operatorname{p_{2}}{\left(t \right)}\\g \operatorname{x_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{p_{1}}{\left(t \right)} + \left(2 \mu e{\left(t \right)} + 1\right) \operatorname{x_{1}}{\left(t \right)}\\g \operatorname{x_{1}}{\left(t \right)} + \operatorname{x_{2}}{\left(t \right)}\end{matrix}\right]$

```python
dx1=diff(x1,t)
dx2=diff(x2,t)
dp1=diff(p1,t)
dp2=diff(p2,t)
dc=diff(c,t)

```

```python
despejadas=[(c_eqs[i]).subs({dc:gaga[0],dx1:gaga[1],dx2:gaga[2],dp1:gaga[3],dp2:gaga[4]}) for i in range(10)]
```

```python
despejadas=[despejadas[i].simplify() for i in range(10)]
```

```python
#eqs=list(to_symbols(sol.subs(diff(c,t),0)))
#t=sympy.linear_eq_to_matrix(eqs, [c1,x11,x12,p11,p12])[0]
#t2=sympy.linear_eq_to_matrix(eqs, [c1,x11,x12,p11,p12])[1]

```

```python
covariance=[v11,v12,v13,v14,v22,v23,v24,v33,v34,v44]
coeffs=[(Matrix(despejadas).expand()[i]).collect(diff(covariance[i],t)).coeff(diff(covariance[i],t)) for i in range(len(despejadas))]
coeffs
```

    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

```python
despeje=[diff(covariance[i],t)*coeffs[i] for i in range(len(covariance))]
```

```python
kara=simplify(Matrix(despejadas).expand()-Matrix(despeje))
kara
```

$\displaystyle \left[\begin{matrix}- 1.0 N_{b} \gamma - 2 g \operatorname{v_{14}}{\left(t \right)} + 1.0 \gamma \operatorname{v_{11}}{\left(t \right)} - 0.5 \gamma + 4 \mu e{\left(t \right)} \operatorname{v_{13}}{\left(t \right)} - 2 \operatorname{v_{13}}{\left(t \right)}\\- g \operatorname{v_{13}}{\left(t \right)} - g \operatorname{v_{24}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{12}}{\left(t \right)} + 2 \mu e{\left(t \right)} \operatorname{v_{23}}{\left(t \right)} - \operatorname{v_{14}}{\left(t \right)} - \operatorname{v_{23}}{\left(t \right)}\\g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} + 1.0 \gamma \operatorname{v_{13}}{\left(t \right)} + 2 \mu e{\left(t \right)} \operatorname{v_{11}}{\left(t \right)} + 2 \mu e{\left(t \right)} \operatorname{v_{33}}{\left(t \right)} + \operatorname{v_{11}}{\left(t \right)} - \operatorname{v_{33}}{\left(t \right)}\\g \operatorname{v_{11}}{\left(t \right)} - g \operatorname{v_{44}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{14}}{\left(t \right)} + 2 \mu e{\left(t \right)} \operatorname{v_{34}}{\left(t \right)} + \operatorname{v_{12}}{\left(t \right)} - \operatorname{v_{34}}{\left(t \right)}\\- 2 g \operatorname{v_{23}}{\left(t \right)} - 2 \operatorname{v_{24}}{\left(t \right)}\\g \operatorname{v_{22}}{\left(t \right)} - g \operatorname{v_{33}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{23}}{\left(t \right)} + 2 \mu e{\left(t \right)} \operatorname{v_{12}}{\left(t \right)} + \operatorname{v_{12}}{\left(t \right)} - \operatorname{v_{34}}{\left(t \right)}\\g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} + \operatorname{v_{22}}{\left(t \right)} - \operatorname{v_{44}}{\left(t \right)}\\- N_{b} \gamma + 2 g \operatorname{v_{23}}{\left(t \right)} + \gamma \operatorname{v_{33}}{\left(t \right)} - \frac{\gamma}{2} + 4 \mu e{\left(t \right)} \operatorname{v_{13}}{\left(t \right)} + 2 \operatorname{v_{13}}{\left(t \right)}\\g \operatorname{v_{13}}{\left(t \right)} + g \operatorname{v_{24}}{\left(t \right)} + 0.5 \gamma \operatorname{v_{34}}{\left(t \right)} + 2 \mu e{\left(t \right)} \operatorname{v_{14}}{\left(t \right)} + \operatorname{v_{14}}{\left(t \right)} + \operatorname{v_{23}}{\left(t \right)}\\2 g \operatorname{v_{14}}{\left(t \right)} + 2 \operatorname{v_{24}}{\left(t \right)}\end{matrix}\right]$

```python
v111,v112,v113,v114 = symbols('v_11:15')
v122,v123,v124 = symbols('v_22:25')
v133,v134=symbols('v_33 v_34')
v144=symbols('v_44')
```

```python
subsss={v11:v111,v12:v112,v13:v113,v14:v114,v22:v122,v23:v123,v24:v124,v33:v133,v34:v134,v44:v144,diff(c1,t):0,(c1**2):c1}
```

```python
to_symbols(kara.subs(subsss))
```

$\displaystyle \left[\begin{matrix}- 1.0 N_{b} \gamma + 4 e \mu v_{13} - 2 g v_{14} + 1.0 \gamma v_{11} - 0.5 \gamma - 2 v_{13}\\2 e \mu v_{23} - g v_{13} - g v_{24} + 0.5 \gamma v_{12} - v_{14} - v_{23}\\2 e \mu v_{11} + 2 e \mu v_{33} + g v_{12} - g v_{34} + 1.0 \gamma v_{13} + v_{11} - v_{33}\\2 e \mu v_{34} + g v_{11} - g v_{44} + 0.5 \gamma v_{14} + v_{12} - v_{34}\\- 2 g v_{23} - 2 v_{24}\\2 e \mu v_{12} + g v_{22} - g v_{33} + 0.5 \gamma v_{23} + v_{12} - v_{34}\\g v_{12} - g v_{34} + v_{22} - v_{44}\\- N_{b} \gamma + 4 e \mu v_{13} + 2 g v_{23} + \gamma v_{33} - \frac{\gamma}{2} + 2 v_{13}\\2 e \mu v_{14} + g v_{13} + g v_{24} + 0.5 \gamma v_{34} + v_{14} + v_{23}\\2 g v_{14} + 2 v_{24}\end{matrix}\right]$

```python
full_dvect=Matrix(list(vector)+list(diff(Matrix(covariance),t)))
full_dvect
```

$\displaystyle \left[\begin{matrix}\frac{d}{d t} c{\left(t \right)}\\\frac{d}{d t} \operatorname{x_{1}}{\left(t \right)}\\\frac{d}{d t} \operatorname{x_{2}}{\left(t \right)}\\\frac{d}{d t} \operatorname{p_{1}}{\left(t \right)}\\\frac{d}{d t} \operatorname{p_{2}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{11}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{12}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{13}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{14}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{22}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{23}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{24}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{33}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{34}}{\left(t \right)}\\\frac{d}{d t} \operatorname{v_{44}}{\left(t \right)}\end{matrix}\right]$

```python
full_vect=Matrix([c1,x11,x12,p11,p12,v111,v112,v113,v114,v122,v123,v124,v133,v134,v144])
full_vect
```

$\displaystyle \left[\begin{matrix}c\\x_{1}\\x_{2}\\p_{1}\\p_{2}\\v_{11}\\v_{12}\\v_{13}\\v_{14}\\v_{22}\\v_{23}\\v_{24}\\v_{33}\\v_{34}\\v_{44}\end{matrix}\right]$

```python
full_eqs=Matrix(list(to_symbols(sol))+list(to_symbols(kara.subs(subsss))))
```

```python
tocheck=[full_eqs[i].expand().subs(Nb,Nb*c1).subs(c1**2,c1).subs(c1*x12,x12).subs(c1*x11,x11).subs(c1*p11,p11).subs(c1*p12,p12) for i in range(len(full_eqs))]
Matrix(tocheck)
```

$\displaystyle \left[\begin{matrix}0\\2 e \mu p_{1} - g p_{2} + 0.5 \gamma x_{1} - p_{1}\\- g p_{1} - p_{2}\\2 e \mu x_{1} + g x_{2} + 0.5 \gamma p_{1} + x_{1}\\g x_{1} + x_{2}\\- 1.0 N_{b} c \gamma + 4 e \mu v_{13} - 2 g v_{14} + 1.0 \gamma v_{11} - 0.5 \gamma - 2 v_{13}\\2 e \mu v_{23} - g v_{13} - g v_{24} + 0.5 \gamma v_{12} - v_{14} - v_{23}\\2 e \mu v_{11} + 2 e \mu v_{33} + g v_{12} - g v_{34} + 1.0 \gamma v_{13} + v_{11} - v_{33}\\2 e \mu v_{34} + g v_{11} - g v_{44} + 0.5 \gamma v_{14} + v_{12} - v_{34}\\- 2 g v_{23} - 2 v_{24}\\2 e \mu v_{12} + g v_{22} - g v_{33} + 0.5 \gamma v_{23} + v_{12} - v_{34}\\g v_{12} - g v_{34} + v_{22} - v_{44}\\- N_{b} c \gamma + 4 e \mu v_{13} + 2 g v_{23} + \gamma v_{33} - \frac{\gamma}{2} + 2 v_{13}\\2 e \mu v_{14} + g v_{13} + g v_{24} + 0.5 \gamma v_{34} + v_{14} + v_{23}\\2 g v_{14} + 2 v_{24}\end{matrix}\right]$

```python
len(tocheck)
```

    15

```python
t=sympy.linear_eq_to_matrix(tocheck, list(full_vect))[0]
t2=sympy.linear_eq_to_matrix(tocheck, list(full_vect))[1]
```

```python
vector

```

$\displaystyle \left[\begin{matrix}\frac{d}{d t} c{\left(t \right)}\\\frac{d}{d t} \operatorname{x_{1}}{\left(t \right)}\\\frac{d}{d t} \operatorname{x_{2}}{\left(t \right)}\\\frac{d}{d t} \operatorname{p_{1}}{\left(t \right)}\\\frac{d}{d t} \operatorname{p_{2}}{\left(t \right)}\end{matrix}\right]$

```python
sol
```

$\displaystyle \left[\begin{matrix}0\\- g \operatorname{p_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{x_{1}}{\left(t \right)} - \operatorname{p_{1}}{\left(t \right)}\\- g \operatorname{p_{1}}{\left(t \right)} - \operatorname{p_{2}}{\left(t \right)}\\g \operatorname{x_{2}}{\left(t \right)} + 0.5 \gamma \operatorname{p_{1}}{\left(t \right)} - \sqrt{2} \mu c{\left(t \right)} e{\left(t \right)} + \operatorname{x_{1}}{\left(t \right)}\\g \operatorname{x_{1}}{\left(t \right)} + \operatorname{x_{2}}{\left(t \right)}\end{matrix}\right]$

```python
full_vect[11]
```

$\displaystyle v_{24}$

```python
((t*full_vect)[11]).subs({p12:0,x11:0,p11:0,v122:0,x12:0,v114:0,v124:0}).subs({e1:e,de1:de}).factor()
```

$\displaystyle g v_{12} - g v_{34} - v_{44}$

```python
ricard=r[1,3].subs(vector[4],sol[4]).expand().collect(covariance[4]).collect(p1).collect(p2).subs(c*x1,x1).collect(x1).subs(c*x2,x2).collect(x2).collect(v12).subs(vector[0],0).subs(c**2,c).collect(c)
simplify(ricard.subs({p2:0,x1:0,p1:0,full_dvect[11]:0,v22:0,x2:0,v14:0,v24:0})).expand().factor()
```

$\displaystyle g \operatorname{v_{12}}{\left(t \right)} - g \operatorname{v_{34}}{\left(t \right)} - \operatorname{v_{44}}{\left(t \right)}$

```python
lista=[]
for i in range(15):
    dummy=[simplify(t[i,j].subs({e1:e,de1:de})) for j in range(15)]
    lista.append(dummy)
```

```python
matriz=Matrix(lista)
matriz
```

$\displaystyle \left[\begin{array}{ccccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0.5 \gamma & 0 & 2 \mu e{\left(t \right)} - 1 & - g & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & - g & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 2 \mu e{\left(t \right)} + 1 & g & 0.5 \gamma & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & g & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\- 1.0 N_{b} \gamma & 0 & 0 & 0 & 0 & 1.0 \gamma & 0 & 4 \mu e{\left(t \right)} - 2 & - 2 g & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0.5 \gamma & - g & -1 & 0 & 2 \mu e{\left(t \right)} - 1 & - g & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} + 1 & g & 1.0 \gamma & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} - 1 & - g & 0\\0 & 0 & 0 & 0 & 0 & g & 1 & 0 & 0.5 \gamma & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} - 1 & - g\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 2 g & -2 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} + 1 & 0 & 0 & g & 0.5 \gamma & 0 & - g & -1 & 0\\0 & 0 & 0 & 0 & 0 & 0 & g & 0 & 0 & 1 & 0 & 0 & 0 & - g & -1\\- N_{b} \gamma & 0 & 0 & 0 & 0 & 0 & 0 & 4 \mu e{\left(t \right)} + 2 & 0 & 0 & 2 g & 0 & \gamma & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & g & 2 \mu e{\left(t \right)} + 1 & 0 & 1 & g & 0 & 0.5 \gamma & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 g & 0 & 0 & 2 & 0 & 0 & 0\end{array}\right]$

```python
matriz[5,0]+=-gamma/2
matriz[12,0]+=-gamma/2
matriz
```

$\displaystyle \left[\begin{array}{ccccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0.5 \gamma & 0 & 2 \mu e{\left(t \right)} - 1 & - g & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & - g & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 2 \mu e{\left(t \right)} + 1 & g & 0.5 \gamma & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & g & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\- 1.0 N_{b} \gamma - \frac{\gamma}{2} & 0 & 0 & 0 & 0 & 1.0 \gamma & 0 & 4 \mu e{\left(t \right)} - 2 & - 2 g & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0.5 \gamma & - g & -1 & 0 & 2 \mu e{\left(t \right)} - 1 & - g & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} + 1 & g & 1.0 \gamma & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} - 1 & - g & 0\\0 & 0 & 0 & 0 & 0 & g & 1 & 0 & 0.5 \gamma & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} - 1 & - g\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 2 g & -2 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 2 \mu e{\left(t \right)} + 1 & 0 & 0 & g & 0.5 \gamma & 0 & - g & -1 & 0\\0 & 0 & 0 & 0 & 0 & 0 & g & 0 & 0 & 1 & 0 & 0 & 0 & - g & -1\\- N_{b} \gamma - \frac{\gamma}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 4 \mu e{\left(t \right)} + 2 & 0 & 0 & 2 g & 0 & \gamma & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & g & 2 \mu e{\left(t \right)} + 1 & 0 & 1 & g & 0 & 0.5 \gamma & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 g & 0 & 0 & 2 & 0 & 0 & 0\end{array}\right]$

```python
t0=Symbol("t0")
A=matriz[5:,5:]
A
```

$\displaystyle \left[\begin{matrix}1.0 \gamma & 0 & -2.0 & - 2.0 g & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0.5 \gamma & - g & -1 & 0 & -1 & - g & 0 & 0 & 0\\1 & g & \gamma & 0 & 0 & 0 & 0 & -1 & - g & 0\\g & 1 & 0 & 0.5 \gamma & 0 & 0 & 0 & 0 & -1 & - g\\0 & 0 & 0 & 0 & 0 & - 2 g & -2 & 0 & 0 & 0\\0 & 1 & 0 & 0 & g & 0.5 \gamma & 0 & - g & -1 & 0\\0 & g & 0 & 0 & 1 & 0 & 0 & 0 & - g & -1\\0 & 0 & 2 & 0 & 0 & 2 g & 0 & \gamma & 0 & 0\\0 & 0 & g & 1 & 0 & 1 & g & 0 & 0.5 \gamma & 0\\0 & 0 & 0 & 2 g & 0 & 0 & 2 & 0 & 0 & 0\end{matrix}\right]$

```python
matriz*full_vect
```

$\displaystyle \left[\begin{matrix}0\\- g p_{2} + 0.5 \gamma x_{1} + p_{1} \left(2 \mu e{\left(t \right)} - 1\right)\\- g p_{1} - p_{2}\\g x_{2} + 0.5 \gamma p_{1} + x_{1} \left(2 \mu e{\left(t \right)} + 1\right)\\g x_{1} + x_{2}\\c \left(- 1.0 N_{b} \gamma - \frac{\gamma}{2}\right) - 2 g v_{14} + 1.0 \gamma v_{11} + v_{13} \left(4 \mu e{\left(t \right)} - 2\right)\\- g v_{13} - g v_{24} + 0.5 \gamma v_{12} - v_{14} + v_{23} \left(2 \mu e{\left(t \right)} - 1\right)\\g v_{12} - g v_{34} + 1.0 \gamma v_{13} + v_{11} \left(2 \mu e{\left(t \right)} + 1\right) + v_{33} \left(2 \mu e{\left(t \right)} - 1\right)\\g v_{11} - g v_{44} + 0.5 \gamma v_{14} + v_{12} + v_{34} \left(2 \mu e{\left(t \right)} - 1\right)\\- 2 g v_{23} - 2 v_{24}\\g v_{22} - g v_{33} + 0.5 \gamma v_{23} + v_{12} \left(2 \mu e{\left(t \right)} + 1\right) - v_{34}\\g v_{12} - g v_{34} + v_{22} - v_{44}\\c \left(- N_{b} \gamma - \frac{\gamma}{2}\right) + 2 g v_{23} + \gamma v_{33} + v_{13} \left(4 \mu e{\left(t \right)} + 2\right)\\g v_{13} + g v_{24} + 0.5 \gamma v_{34} + v_{14} \left(2 \mu e{\left(t \right)} + 1\right) + v_{23}\\2 g v_{14} + 2 v_{24}\end{matrix}\right]$

```python
Matrix(tocheck)
```

$\displaystyle \left[\begin{matrix}0\\2 e \mu p_{1} - g p_{2} + 0.5 \gamma x_{1} - p_{1}\\- g p_{1} - p_{2}\\2 e \mu x_{1} + g x_{2} + 0.5 \gamma p_{1} + x_{1}\\g x_{1} + x_{2}\\- 1.0 N_{b} c \gamma + 4 e \mu v_{13} - 2 g v_{14} + 1.0 \gamma v_{11} - 0.5 \gamma - 2 v_{13}\\2 e \mu v_{23} - g v_{13} - g v_{24} + 0.5 \gamma v_{12} - v_{14} - v_{23}\\2 e \mu v_{11} + 2 e \mu v_{33} + g v_{12} - g v_{34} + 1.0 \gamma v_{13} + v_{11} - v_{33}\\2 e \mu v_{34} + g v_{11} - g v_{44} + 0.5 \gamma v_{14} + v_{12} - v_{34}\\- 2 g v_{23} - 2 v_{24}\\2 e \mu v_{12} + g v_{22} - g v_{33} + 0.5 \gamma v_{23} + v_{12} - v_{34}\\g v_{12} - g v_{34} + v_{22} - v_{44}\\- N_{b} c \gamma + 4 e \mu v_{13} + 2 g v_{23} + \gamma v_{33} - \frac{\gamma}{2} + 2 v_{13}\\2 e \mu v_{14} + g v_{13} + g v_{24} + 0.5 \gamma v_{34} + v_{14} + v_{23}\\2 g v_{14} + 2 v_{24}\end{matrix}\right]$

```python
H0=simplify(matriz.subs({e:0}))
He=simplify(matriz.subs({de:0})-H0)
```

```python
He=He/e
```

```python
H0
```

$\displaystyle \left[\begin{array}{ccccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0.5 \gamma & 0 & -1 & - g & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & - g & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & g & 0.5 \gamma & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & g & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\- \gamma \left(1.0 N_{b} + 0.5\right) & 0 & 0 & 0 & 0 & 1.0 \gamma & 0 & -2 & - 2 g & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0.5 \gamma & - g & -1 & 0 & -1 & - g & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 1 & g & 1.0 \gamma & 0 & 0 & 0 & 0 & -1 & - g & 0\\0 & 0 & 0 & 0 & 0 & g & 1 & 0 & 0.5 \gamma & 0 & 0 & 0 & 0 & -1 & - g\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 2 g & -2 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & g & 0.5 \gamma & 0 & - g & -1 & 0\\0 & 0 & 0 & 0 & 0 & 0 & g & 0 & 0 & 1 & 0 & 0 & 0 & - g & -1\\- \gamma \left(N_{b} + \frac{1}{2}\right) & 0 & 0 & 0 & 0 & 0 & 0 & 2 & 0 & 0 & 2 g & 0 & \gamma & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & g & 1 & 0 & 1 & g & 0 & 0.5 \gamma & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 g & 0 & 0 & 2 & 0 & 0 & 0\end{array}\right]$

```python
He
```

$\displaystyle \left[\begin{array}{ccccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 2 \mu & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 2 \mu & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 4 \mu & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 \mu & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 2 \mu & 0 & 0 & 0 & 0 & 0 & 0 & 2 \mu & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 \mu & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 2 \mu & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 4 \mu & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 \mu & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\end{array}\right]$

```python
hlineal=lambdify((mu),He)
import dill
dill.settings['recurse'] = True
```

```python
dill.dump(hlineal, open("H_campo", "wb"))

```

```python
Hde=Hde/de
```

```python
Hde=simplify(Hde)
```

```python
Hde
```

```python
func=lambdify((mu,g),Hde)
```

```python
Matrix(func(2,0.1))
```

```python
H0
```

```python
h0lineal=lambdify((g,gamma,Nb),H0)
h0lineal(0.2,1,0.5)
```

    array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,
             0. ,  0. ,  0. ,  0. ],
           [ 0. ,  0.5,  0. , -1. , -0.2,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,
             0. ,  0. ,  0. ,  0. ],
           [ 0. ,  0. ,  0. , -0.2, -1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,
             0. ,  0. ,  0. ,  0. ],
           [ 0. ,  1. ,  0.2,  0.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,
             0. ,  0. ,  0. ,  0. ],
           [ 0. ,  0.2,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,
             0. ,  0. ,  0. ,  0. ],
           [-1. ,  0. ,  0. ,  0. ,  0. ,  1. ,  0. , -2. , -0.4,  0. ,  0. ,
             0. ,  0. ,  0. ,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0.5, -0.2, -1. ,  0. , -1. ,
            -0.2,  0. ,  0. ,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  1. ,  0.2,  1. ,  0. ,  0. ,  0. ,
             0. , -1. , -0.2,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0.2,  1. ,  0. ,  0.5,  0. ,  0. ,
             0. ,  0. , -1. , -0.2],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , -0.4,
            -2. ,  0. ,  0. ,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  1. ,  0. ,  0. ,  0.2,  0.5,
             0. , -0.2, -1. ,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0.2,  0. ,  0. ,  1. ,  0. ,
             0. ,  0. , -0.2, -1. ],
           [-1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  2. ,  0. ,  0. ,  0.4,
             0. ,  1. ,  0. ,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0.2,  1. ,  0. ,  1. ,
             0.2,  0. ,  0.5,  0. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0.4,  0. ,  0. ,
             2. ,  0. ,  0. ,  0. ]])

```python
dill.dump(h0lineal, open("H_0", "wb"))

```

```python
H0
```

```python
from Integrals import overlap2
```

```python
vector1=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
vector2=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

```

```python
V=[[vector1[5],vector1[6],vector1[7],vector1[8]],[1,vector1[9],vector1[10],vector1[11]],[1,1,vector1[12],vector1[13]],[1,1,1,vector1[14]]]
R=[vector1[i] for i in range(1,5)]
B=[[vector2[5],vector2[6],vector2[7],vector2[8]],[1,vector2[9],vector2[10],vector2[11]],[1,1,vector2[12],vector2[13]],[1,1,1,vector2[14]]]
S=[vector2[i] for i in range(1,5)]
```

```python
V
```

```python
R
```

```python
B
```

```python
S
```

```python
overlap2(vector1,vector2)
```

```python
(e*de)
```

```python
sp.sin(2)*sp.cos(2)
```

```python

```

```python

```

```python

```


```python
# %load ../../imports.py
"""
These is the standard setup for the notebooks.
"""

%matplotlib inline
%load_ext autoreload
%autoreload 2

#jtplot.style(theme='onedork', context='notebook', ticks=True, grid=False)

import warnings
warnings.filterwarnings("ignore")
from pylab import rcParams
#rcParams['figure.figsize'] = 15, 8
rcParams['figure.figsize'] = 10, 6

import pandas as pd
pd.options.display.max_rows = 999
pd.options.display.max_columns = 999
pd.set_option("display.max_columns", None)
import numpy as np
import os
import matplotlib.pyplot as plt
plt.style.use('paper')

#import data
import copy
from rolldecay.bis_system import BisSystem
from rolldecay import database
from mdldb.tables import Run

from sklearn.pipeline import Pipeline
from rolldecayestimators.transformers import CutTransformer, LowpassFilterDerivatorTransformer, ScaleFactorTransformer, OffsetTransformer
from rolldecayestimators.direct_estimator_cubic import EstimatorQuadraticB, EstimatorCubic
from rolldecayestimators.ikeda_estimator import IkedaQuadraticEstimator
import rolldecayestimators.equations as equations
import rolldecayestimators.lambdas as lambdas
from rolldecayestimators.substitute_dynamic_symbols import lambdify
import rolldecayestimators.symbols as symbols
import sympy as sp

from sklearn.metrics import r2_score

```

```python
import matplotlib
print(matplotlib.matplotlib_fname())
```

```python
from collections import OrderedDict
from rolldecayestimators.simplified_ikeda_class import SimplifiedIkeda, SimplifiedIkedaABS
from rolldecayestimators.simplified_ikeda import limits_kawahara
import rolldecay.paper_writing as paper_writing
```

```python
limits_kawahara
```

```python
db = database.get_db()

sql =  """
SELECT * from
loading_conditions
INNER JOIN models
    ON loading_conditions.model_number==models.model_number
    INNER JOIN ships
        ON ships.name == models.ship_name
"""
df_loading_conditions = pd.read_sql_query(sql=sql, con=db.engine)
```

```python
loading_condition = df_loading_conditions.median()
#loading_condition = df_loading_conditions.mean()

#df_loading_conditions = df_loading_conditions.select_dtypes(include=np.number)
#loading_condition = (df_loading_conditions.max() - df_loading_conditions.min())/2 + df_loading_conditions.min()
```

```python
fi_a=np.deg2rad(10)
beam=loading_condition.beam
lpp=loading_condition.lpp
kg=loading_condition.kg
volume=loading_condition.Volume
draught=loading_condition.TA
A0=loading_condition.A0
lBK=loading_condition.BKL
bBK=loading_condition.BKB
scale_factor=loading_condition.scale_factor
```

```python
input = pd.Series()
input['g']=9.81
input['omega_hat']=np.mean(limits_kawahara['OMEGA_hat'])
input['fi_a']=fi_a
input['beam']=beam/scale_factor
input['lpp']=lpp/scale_factor
input['kg']=kg/scale_factor
input['volume']=volume/(scale_factor**3)
input['draught']=draught/scale_factor
input['A0']=A0
input['lBK']=lBK/scale_factor
input['bBK']=bBK/scale_factor
```

```python
input['w']= lambdas.omega(beam=input['beam'], g=input['g'], omega_hat=input['omega_hat'])
input['Fn']=0.1
input['V'] = input['Fn']*np.sqrt(input['lpp']*input['g'])
```

```python
N = 100
data = np.tile(input.values,(N,1))
inputs_raw = pd.DataFrame(data=data, columns=input.index)
```

```python
equations.B_1_hat_equation
```

```python
def calculate(inputs, IkedaClass=SimplifiedIkeda):
    si = IkedaClass(**inputs)
    output = inputs.copy()
    output['B_44_hat'] = si.calculate_B44()
    output['B_W0'] =si.calculate_B_W0()
    output['B_W'] =si.calculate_B_W()
    output['B_F'] =si.calculate_B_F()
    output['B_E'] =si.calculate_B_E()
    output['B_BK'] =si.calculate_B_BK()
    output['B_L'] =si.calculate_B_L()
    output['Bw_div_Bw0'] =si.calculate_Bw_div_Bw0()

    return output
```

```python
Fns=np.linspace(0,0.2,5)
fig,ax=plt.subplots()

for Fn in Fns:

    inputs = inputs_raw.copy()
    inputs['fi_a']=np.deg2rad(np.linspace(1,15,N))
    inputs['V']=Fn*np.sqrt(inputs['lpp']*inputs['g'])

    output = calculate(inputs=inputs)
    output['B_44_hat']-=output.iloc[0]['B_44_hat']

    output.plot(x='fi_a', y='B_44_hat',label='Fn=%0.2f'%Fn, ax=ax);
    ax.set_xlabel(r'$\phi_a$')
    ax.set_ylabel(r'$\hat{B_{44}}$')
```

```python
inputs = inputs_raw.copy()
inputs['Fn']=np.linspace(0,0.1,N)
inputs['V']=inputs['Fn']*np.sqrt(inputs['lpp']*inputs['g'])

output = calculate(inputs=inputs)

#fig,ax=plt.subplots()
#output.plot(x='Fn', y='B_44_hat', label=r'$\hat{B_{44}}$', ax=ax);
#
#fig,ax=plt.subplots()
#output.plot.area(x='Fn', y = ['B_BK','B_F','B_E','B_L','B_W',], ax=ax)
#
#fig,ax=plt.subplots()
#output.plot(x='Fn', y='Bw_div_Bw0', ax=ax);
#ax.grid(True)
#ax.set_xlabel(r'$F_n$');
```

```python
#inputs = inputs_raw.copy()
#x='OG/d'
#inputs[x]=np.linspace(limits_kawahara[x][0],limits_kawahara[x][1],N)
#inputs['OG'] = inputs['OG/d']*inputs['draught']
#inputs['kg'] = -inputs['OG'] + inputs['draught']
#
#output = calculate(inputs=inputs)
#
#fig,ax=plt.subplots()
#output.plot.area(x=x, y = ['B_BK','B_F','B_E','B_L','B_W',], ax=ax)
```

```python
#inputs = inputs_raw.copy()
#x='fi_a'
#inputs[x]=np.deg2rad(np.linspace(1,15,N))
#
#output = calculate(inputs=inputs)
#
#fig,ax=plt.subplots()
#output.plot.area(x=x, y = ['B_BK','B_F','B_E','B_L','B_W',], ax=ax)
```

```python
df_rolldecay = database.load(rolldecay_table_name='rolldecay_quadratic_b', limit_score=0.99,
                             exclude_table_name='rolldecay_exclude')

df_rolldecay_raw = df_rolldecay.copy()

scale_factor=df_rolldecay['scale_factor']
df_rolldecay['lpp']/=scale_factor
df_rolldecay['TA']/=scale_factor
df_rolldecay['TF']/=scale_factor
df_rolldecay['draught']=(df_rolldecay['TA'] + df_rolldecay['TF'])/2
df_rolldecay['beam']/=scale_factor
df_rolldecay['BKL']/=scale_factor
df_rolldecay['BKB']/=scale_factor
#df_rolldecay['A0']=db_run.loading_condition.A0
df_rolldecay['kg']/=scale_factor
df_rolldecay['Volume']/=(scale_factor**3)
df_rolldecay['gm']/=scale_factor
df_rolldecay['V']=df_rolldecay['ship_speed']*1.852/3.6/np.sqrt(scale_factor)  #[m/s]
df_rolldecay['rho']=rho=1000
df_rolldecay['g']=g=9.81

df_rolldecay['Fn']=df_rolldecay['V']/np.sqrt(df_rolldecay['lpp']*df_rolldecay['g'])
df_rolldecay['CB']=df_rolldecay['Volume']/(df_rolldecay['lpp']*df_rolldecay['draught']*df_rolldecay['beam'])
df_rolldecay['B/d']=df_rolldecay['beam']/df_rolldecay['draught']
df_rolldecay['OG']=-(df_rolldecay['kg']-df_rolldecay['draught'])
df_rolldecay[r'OG/d']=df_rolldecay['OG']/df_rolldecay['draught']
df_rolldecay['CMID']=df_rolldecay['A0']
df_rolldecay[r'bBk/B']=df_rolldecay['BKB']/df_rolldecay['beam']
df_rolldecay[r'lBk/LPP']=df_rolldecay['BKL']/df_rolldecay['lpp']
df_rolldecay['OMEGA_hat']=lambdas.omega_hat(beam=df_rolldecay.beam, g=df_rolldecay['g'],
                                            omega0=df_rolldecay['omega0'])

```

```python
def CB_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df['CB']=values
    df['volume']=df['CB']*df['lpp']*df['beam']*df['draught']
    return df

def BD_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'B/d']=values
    df['beam']=df[r'B/d']*df['draught']
    return df

def OGd_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'OG/d']=values
    df['OG']=df[r'OG/d']*df['draught']
    df['kg']=-df['OG']+df['draught']
    return df

def CMIDchanger(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'A0']=df[r'CMID']=values
    return df

def bBK_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'bBk/B']=values
    df['bBK']=df[r'bBk/B']*df['beam']
    return df

def lBK_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'lBk/LPP']=values
    df['lBK']=df[r'lBk/LPP']*df['lpp']
    return df

def omega_hat_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df['OMEGA_hat']=values
    df['w']=lambdas.omega(beam=input['beam'], g=input['g'], omega_hat=df['OMEGA_hat'])
    return df

def phi_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'fi_a']=np.deg2rad(values)
    return df

def fn_changer(df, limits):
    values = np.linspace(limits[0], limits[1], len(df))
    df[r'Fn']=values
    df['V']=df['Fn']*np.sqrt(df['lpp']*df['g'])
    return df

changers = OrderedDict()
changers['CB'] = CB_changer
changers[r'B/d'] = BD_changer
changers[r'OG/d'] = OGd_changer
changers['CMID'] = CMIDchanger
#changers[r'bBk/B'] = bBK_changer
#changers[r'lBk/LPP'] = lBK_changer
changers[r'OMEGA_hat'] = omega_hat_changer
#changers[r'fi_a'] = phi_changer
changers[r'Fn'] = fn_changer

labels={
'CB' : r'$C_b$ [-]',
r'B/d' : r'$\frac{beam}{T}$ [-]',
r'OG/d' : r'$\frac{\overline{OG}}{T}$ [-]',
'CMID' : r'$A_{0}$ [-]',
r'bBk/B' : r'$\frac{BK_B}{beam}$ [-]',
r'lBk/LPP' : r'$\frac{BK_L}{L_{pp}}$ [-]',
r'OMEGA_hat' : r'$\hat{\omega}$ [-]',
r'fi_a' : r'$\phi_a$ [rad]',
r'Fn' : r'$F_n$ [-]',

}

limits={key:(df_rolldecay[key].min(),df_rolldecay[key].max()) for key in changers.keys() if key in df_rolldecay}
limits['fi_a'] = (1,10)
limits['Fn'] = (0,0.25)

```

```python
#reference_ship = s = input.copy()
#s['CB'] = s['volume']/(s['lpp']*s['beam']*s['draught'])
#s[r'B/d'] = s['beam']/s['draught']
#s[r'OG'] =s['draught']-s['kg']
#s[r'OG/d'] = s['OG']/s['draught']
#s['CMID'] = s['A0']
#s[r'bBk/B'] = s['bBK']/s['lpp']
#s[r'lBk/LPP'] = s['lBK']/s['lpp']
#s[r'OMEGA_hat'] = lambdas.omega_hat(beam=s['beam'], g=g, omega0=s['w'])
#s[r'fi_a'] = fi_a
#s[r'Fn'] = s['Fn']
```

```python
#reference_ship = {key:df_rolldecay[key].mean() for key in changers.keys() if key in df_rolldecay}
reference_ship = {key:np.mean(limits_kawahara[key]) for key in changers.keys() if key in limits_kawahara}

reference_ship['fi_a'] = np.mean(np.deg2rad((1,10)))
reference_ship['Fn'] = np.mean((0,0.25))
```

```python
N = 100
reference_ship=pd.Series(reference_ship)
data = np.tile(reference_ship.values,(N,1))
inputs_raw = pd.DataFrame(data=data, columns=reference_ship.index)
inputs_raw['lpp']=df_rolldecay['lpp'].mean()
inputs_raw['beam']=df_rolldecay['beam'].mean()
inputs_raw['draught']=df_rolldecay['draught'].mean()
inputs_raw['g']=g
inputs_raw['rho']=rho
#df_rolldecay['Cb']=df_rolldecay['Volume']/(df_rolldecay['lpp']*df_rolldecay['beam']*df_rolldecay['draught'])
#inputs_raw['Cb']=df_rolldecay['Cb'].mean()
#inputs_raw['volume']=inputs_raw['Cb']*inputs_raw['lpp']*inputs_raw['beam']*inputs_raw['draught']

for key, changer in changers.items():
    value = reference_ship[key]
    changer(inputs_raw,(value,value))

```

```python
import matplotlib.patches as patches

fig = plt.figure()
fig.set_size_inches(7,7)

ncols=3
#nrows=2*3
nrows=2*2
left_pad=0.09
right_pad=0.01
top_pad=0.00
bottom_pad=0.10

top_padders = [0.0, 0.00]
top_pads = np.tile(top_padders,(1,int(nrows/2)))[0]

bottom_padders = [0.0, 0.10]
bottom_pads = np.tile(bottom_padders,(1,int(nrows/2)))[0]

left_padders = np.ones(ncols)*0.02
right_padders = 0.0

dX=1/ncols
dx=(1-left_pad-right_pad)/ncols
dx_prims = dx - left_padders - right_padders
xs = np.arange(0,ncols)*(dx) + left_pad + left_padders

y_ratios=np.array([1.0,4.0])
dys=np.tile(y_ratios,(1,int(nrows/2)))[0]
dys/=np.sum(dys)
dys*=(1-bottom_pad-top_pad)
dys-=(top_pads + bottom_pads)

ys = np.cumsum(dys + top_pads + bottom_pads)
ys = np.concatenate(([0],ys[:-1])) + bottom_pad
ys = np.flipud(ys)
dys = np.flipud(dys)

axes=[]
for y,dy in zip(ys,dys):
    row=[]
    for x,dx_prim in zip(xs,dx_prims):
        ax = fig.add_axes([x,y,dx_prim,dy])
        #ax.get_xaxis().set_visible(False)
        #ax.get_yaxis().set_visible(False)
        row.append(ax)
    axes.append(row)

ylims=[]
ylims1=[]
#axes=axes.flatten()
ylim=0.045
for i,(x, changer) in enumerate(changers.items()):

    # Add model test results:
    row=i//ncols
    col=i%ncols
    ax1=axes[row*2+1][col]

    if x in df_rolldecay:
        df_rolldecay.hist(x,ax=ax1, bins=20)

    ax1.set_title(None)
    ax1.grid(False)
    ylims1.append(ax1.get_ylim()[1])
    xlabel=labels[x]
    ax1.set_xlabel(xlabel)

    ax=axes[row*2][col]
    lims=limits[x]

    inputs = inputs_raw.copy()
    inputs = changer(df=inputs, limits=lims)
    output = calculate(inputs=inputs, IkedaClass=SimplifiedIkedaABS)

    #lims_extrapolation=limits_extrapolation[x]
    #inputs_extrapolation = inputs_raw.copy()
    #inputs_extrapolation = changer(df=inputs_extrapolation, limits=lims_extrapolation)
    #output_extrapolation = calculate(inputs=inputs_extrapolation, IkedaClass=SimplifiedIkedaABS)

    labels_ = [r'$\hat{B}_{BK}$',r'$\hat{B}_F$',r'$\hat{B}_E$',r'$\hat{B}_L$',r'$\hat{B}_W$']

    output.plot.area(x=x, y = ['B_BK','B_F','B_E','B_L','B_W',], label=labels_, ax=ax)
    if x in limits_kawahara:
        lim_=limits_kawahara[x]

        ax.plot([lim_[0],lim_[0]],[0,ylim],'r', label='exceeding limit')
        rect = patches.Rectangle((lim_[0],0),ax.get_xlim()[0]-lim_[0],ylim,linewidth=1,edgecolor='r',facecolor='r', alpha=0.25, hatch='\\')
        ax.add_patch(rect)

        ax.plot([lim_[1],lim_[1]],[0,ylim],'r')
        rect = patches.Rectangle((lim_[1],0),ax.get_xlim()[1]-lim_[1],ylim,linewidth=1,edgecolor='r',facecolor='r', alpha=0.25, hatch='\\')
        ax.add_patch(rect)

    ax.plot([reference_ship[x], reference_ship[x]],[0,ylim], 'k--', label='reference ship')

    ax.get_xaxis().set_visible(False)

    #ax.grid()
    ax.get_legend().remove()
    ylims.append(ax.get_ylim()[1])

    if x in df_rolldecay:
        ax.set_xlim(ax1.get_xlim())
    else:
        ax1.set_xlim(ax.get_xlim())

    if col>0:
        ax.get_yaxis().set_visible(False)
        ax1.get_yaxis().set_visible(False)
    else:
        ax.set_ylabel(r'$\hat{B_{e}}$')
        ax1.set_ylabel(r'ships')

    #ax.spines['top'].set_visible(False)
    #ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    #ax.spines['left'].set_visible(False)
    ax.set_ylim(0,ylim)  # hard coded

    ax1.spines['top'].set_visible(False)
    #ax1.spines['right'].set_visible(False)
    #ax1.spines['bottom'].set_visible(False)
    #ax1.spines['left'].set_visible(False)

#for i,(x, changer) in enumerate(changers.items()):
#    row=i//ncols
#    col=i%ncols
#    ax=axes[row*2][col]
#    ax.set_ylim(0,np.max(ylims))

for i,(x, changer) in enumerate(changers.items()):
    row=i//ncols
    col=i%ncols
    ax=axes[row*2+1][col]
    ax.set_ylim(0,np.max(ylims1))

axes[0][0].legend(loc='upper left')

paper_writing.save_fig(fig=fig, name='SI-sensitivity')
```

```python
dys
```

```python
xs
```

```python
3*dX
```

```python
3*dx
```

```python
np.sum(dx_prims)
```

```python
fig, ax = plt.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)
ax.plot(x, y, color='black')

threshold = 0.75
ax.axhline(threshold, color='green', lw=2, alpha=0.7)
ax.fill_between(x, -3, 2, where=y > threshold,
                color='green', alpha=0.5, transform=ax.get_xaxis_transform())
```

```python
ys
```

```python

```

```python

```

```python

```

```python

```

```python

```

```python

```

```python

```

```python

```

```python

```


# Derivative Linear Equation Stock Data

```python
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

import warnings
warnings.filterwarnings("ignore")

# yfinance is used to fetch data
import yfinance as yf
yf.pdr_override()
```

```python
# input
symbol = 'AMD'
start = '2017-01-01'
end = '2019-01-01'

# Read data
dataset = yf.download(symbol,start,end)['Adj Close']

# View Columns
dataset.head()
```

    [*********************100%***********************]  1 of 1 completed

    Date
    2017-01-03    11.43
    2017-01-04    11.43
    2017-01-05    11.24
    2017-01-06    11.32
    2017-01-09    11.49
    Name: Adj Close, dtype: float64

```python
df = dataset.reset_index()
```

```python
df.head()
```

      Date
      Adj Close

      0
      2017-01-03
      11.43

      1
      2017-01-04
      11.43

      2
      2017-01-05
      11.24

      3
      2017-01-06
      11.32

      4
      2017-01-09
      11.49

```python
df.tail()
```

      Date
      Adj Close

      497
      2018-12-24
      16.650000

      498
      2018-12-26
      17.900000

      499
      2018-12-27
      17.490000

      500
      2018-12-28
      17.820000

      501
      2018-12-31
      18.459999

```python
max_p = df['Adj Close'].max()
min_p = df['Adj Close'].min()
avg_p = df['Adj Close'].mean()
```

```python
data = df.drop(['Date'], axis=1)
data
```

      Adj Close

      0
      11.430000

      1
      11.430000

      2
      11.240000

      3
      11.320000

      4
      11.490000

      5
      11.440000

      6
      11.200000

      7
      10.760000

      8
      10.580000

      9
      9.820000

      10
      9.880000

      11
      9.770000

      12
      9.750000

      13
      9.910000

      14
      10.440000

      15
      10.350000

      16
      10.520000

      17
      10.670000

      18
      10.610000

      19
      10.370000

      20
      12.060000

      21
      12.280000

      22
      12.240000

      23
      13.630000

      24
      13.290000

      25
      13.560000

      26
      13.420000

      27
      13.580000

      28
      13.490000

      29
      13.260000

      ...
      ...

      472
      21.490000

      473
      20.660000

      474
      19.110001

      475
      19.209999

      476
      18.730000

      477
      19.379999

      478
      20.080000

      479
      21.049999

      480
      21.340000

      481
      21.430000

      482
      21.299999

      483
      23.709999

      484
      21.120001

      485
      21.299999

      486
      19.459999

      487
      19.990000

      488
      19.980000

      489
      20.480000

      490
      19.860001

      491
      19.900000

      492
      18.830000

      493
      19.500000

      494
      18.160000

      495
      17.940001

      496
      16.930000

      497
      16.650000

      498
      17.900000

      499
      17.490000

      500
      17.820000

      501
      18.459999

502 rows × 1 columns

```python
data = data.reset_index()
```

```python
data.as_matrix()
```

    array([[  0.        ,  11.43000031],
           [  1.        ,  11.43000031],
           [  2.        ,  11.23999977],
           ...,
           [499.        ,  17.48999977],
           [500.        ,  17.81999969],
           [501.        ,  18.45999908]])

```python
from numpy import ones,vstack
from numpy.linalg import lstsq
```

```python
points = data.as_matrix()
```

```python
x_coords, y_coords = zip(*points)
A = vstack([x_coords,ones(len(x_coords))]).T
m, c = lstsq(A, y_coords)[0]

```

```python
print("Line Equation is y = {m}x + {c}".format(m=m,c=c))

```

    Line Equation is y = 0.021718614923358824x + 9.372574584656498

```python
equation_of_line = print("y = {m}x + {c}".format(m=m,c=c))

```

    y = 0.021718614923358824x + 9.372574584656498

```python
plt.figure(figsize=(16,8))
plt.plot(dataset)
plt.title('Line of Equation', equation_of_line)
plt.xlabel('x', color='#1C2833')
plt.ylabel('y', color='#1C2833')
plt.legend(loc='best')
plt.grid()
plt.show()
```

```python
from sympy import *
```

```python
x = Symbol('x')
```

```python
y = 0.021718614923358824*x + 9.372574584656498
```

```python
yder = y.diff(x)
yder
```

    0.0217186149233588

```python
y =  0.021718614923358824*(df.index) + 9.372574584656498
```

```python
y
```

    Float64Index([ 9.372574584656498,  9.394293199579856,  9.416011814503216,
                   9.437730429426574,  9.459449044349933,  9.481167659273291,
                   9.502886274196651,   9.52460488912001,  9.546323504043368,
                   9.568042118966726,
                  ...
                  20.058133126949038, 20.079851741872396, 20.101570356795754,
                  20.123288971719116, 20.145007586642475, 20.166726201565833,
                   20.18844481648919, 20.210163431412553,  20.23188204633591,
                   20.25360066125927],
                 dtype='float64', length=502)

```python
pd.DataFrame(y, columns=['Forecast'])
```

      Forecast

      0
      9.372575

      1
      9.394293

      2
      9.416012

      3
      9.437730

      4
      9.459449

      5
      9.481168

      6
      9.502886

      7
      9.524605

      8
      9.546324

      9
      9.568042

      10
      9.589761

      11
      9.611479

      12
      9.633198

      13
      9.654917

      14
      9.676635

      15
      9.698354

      16
      9.720072

      17
      9.741791

      18
      9.763510

      19
      9.785228

      20
      9.806947

      21
      9.828665

      22
      9.850384

      23
      9.872103

      24
      9.893821

      25
      9.915540

      26
      9.937259

      27
      9.958977

      28
      9.980696

      29
      10.002414

      ...
      ...

      472
      19.623761

      473
      19.645479

      474
      19.667198

      475
      19.688917

      476
      19.710635

      477
      19.732354

      478
      19.754073

      479
      19.775791

      480
      19.797510

      481
      19.819228

      482
      19.840947

      483
      19.862666

      484
      19.884384

      485
      19.906103

      486
      19.927821

      487
      19.949540

      488
      19.971259

      489
      19.992977

      490
      20.014696

      491
      20.036415

      492
      20.058133

      493
      20.079852

      494
      20.101570

      495
      20.123289

      496
      20.145008

      497
      20.166726

      498
      20.188445

      499
      20.210163

      500
      20.231882

      501
      20.253601

502 rows × 1 columns

```python
dataset
```

    Date
    2017-01-03    11.430000
    2017-01-04    11.430000
    2017-01-05    11.240000
    2017-01-06    11.320000
    2017-01-09    11.490000
    2017-01-10    11.440000
    2017-01-11    11.200000
    2017-01-12    10.760000
    2017-01-13    10.580000
    2017-01-17     9.820000
    2017-01-18     9.880000
    2017-01-19     9.770000
    2017-01-20     9.750000
    2017-01-23     9.910000
    2017-01-24    10.440000
    2017-01-25    10.350000
    2017-01-26    10.520000
    2017-01-27    10.670000
    2017-01-30    10.610000
    2017-01-31    10.370000
    2017-02-01    12.060000
    2017-02-02    12.280000
    2017-02-03    12.240000
    2017-02-06    13.630000
    2017-02-07    13.290000
    2017-02-08    13.560000
    2017-02-09    13.420000
    2017-02-10    13.580000
    2017-02-13    13.490000
    2017-02-14    13.260000
                    ...
    2018-11-15    21.490000
    2018-11-16    20.660000
    2018-11-19    19.110001
    2018-11-20    19.209999
    2018-11-21    18.730000
    2018-11-23    19.379999
    2018-11-26    20.080000
    2018-11-27    21.049999
    2018-11-28    21.340000
    2018-11-29    21.430000
    2018-11-30    21.299999
    2018-12-03    23.709999
    2018-12-04    21.120001
    2018-12-06    21.299999
    2018-12-07    19.459999
    2018-12-10    19.990000
    2018-12-11    19.980000
    2018-12-12    20.480000
    2018-12-13    19.860001
    2018-12-14    19.900000
    2018-12-17    18.830000
    2018-12-18    19.500000
    2018-12-19    18.160000
    2018-12-20    17.940001
    2018-12-21    16.930000
    2018-12-24    16.650000
    2018-12-26    17.900000
    2018-12-27    17.490000
    2018-12-28    17.820000
    2018-12-31    18.459999
    Name: Adj Close, Length: 502, dtype: float64

```python
forecast = pd.DataFrame(y, columns=['Forecast'])
forecast
```

      Forecast

      0
      9.372575

      1
      9.394293

      2
      9.416012

      3
      9.437730

      4
      9.459449

      5
      9.481168

      6
      9.502886

      7
      9.524605

      8
      9.546324

      9
      9.568042

      10
      9.589761

      11
      9.611479

      12
      9.633198

      13
      9.654917

      14
      9.676635

      15
      9.698354

      16
      9.720072

      17
      9.741791

      18
      9.763510

      19
      9.785228

      20
      9.806947

      21
      9.828665

      22
      9.850384

      23
      9.872103

      24
      9.893821

      25
      9.915540

      26
      9.937259

      27
      9.958977

      28
      9.980696

      29
      10.002414

      ...
      ...

      472
      19.623761

      473
      19.645479

      474
      19.667198

      475
      19.688917

      476
      19.710635

      477
      19.732354

      478
      19.754073

      479
      19.775791

      480
      19.797510

      481
      19.819228

      482
      19.840947

      483
      19.862666

      484
      19.884384

      485
      19.906103

      486
      19.927821

      487
      19.949540

      488
      19.971259

      489
      19.992977

      490
      20.014696

      491
      20.036415

      492
      20.058133

      493
      20.079852

      494
      20.101570

      495
      20.123289

      496
      20.145008

      497
      20.166726

      498
      20.188445

      499
      20.210163

      500
      20.231882

      501
      20.253601

502 rows × 1 columns

```python
df = dataset.reset_index()
```

```python
df = df.join(forecast)
```

```python
df
```

      Date
      Adj Close
      Forecast

      0
      2017-01-03
      11.430000
      9.372575

      1
      2017-01-04
      11.430000
      9.394293

      2
      2017-01-05
      11.240000
      9.416012

      3
      2017-01-06
      11.320000
      9.437730

      4
      2017-01-09
      11.490000
      9.459449

      5
      2017-01-10
      11.440000
      9.481168

      6
      2017-01-11
      11.200000
      9.502886

      7
      2017-01-12
      10.760000
      9.524605

      8
      2017-01-13
      10.580000
      9.546324

      9
      2017-01-17
      9.820000
      9.568042

      10
      2017-01-18
      9.880000
      9.589761

      11
      2017-01-19
      9.770000
      9.611479

      12
      2017-01-20
      9.750000
      9.633198

      13
      2017-01-23
      9.910000
      9.654917

      14
      2017-01-24
      10.440000
      9.676635

      15
      2017-01-25
      10.350000
      9.698354

      16
      2017-01-26
      10.520000
      9.720072

      17
      2017-01-27
      10.670000
      9.741791

      18
      2017-01-30
      10.610000
      9.763510

      19
      2017-01-31
      10.370000
      9.785228

      20
      2017-02-01
      12.060000
      9.806947

      21
      2017-02-02
      12.280000
      9.828665

      22
      2017-02-03
      12.240000
      9.850384

      23
      2017-02-06
      13.630000
      9.872103

      24
      2017-02-07
      13.290000
      9.893821

      25
      2017-02-08
      13.560000
      9.915540

      26
      2017-02-09
      13.420000
      9.937259

      27
      2017-02-10
      13.580000
      9.958977

      28
      2017-02-13
      13.490000
      9.980696

      29
      2017-02-14
      13.260000
      10.002414

      ...
      ...
      ...
      ...

      472
      2018-11-15
      21.490000
      19.623761

      473
      2018-11-16
      20.660000
      19.645479

      474
      2018-11-19
      19.110001
      19.667198

      475
      2018-11-20
      19.209999
      19.688917

      476
      2018-11-21
      18.730000
      19.710635

      477
      2018-11-23
      19.379999
      19.732354

      478
      2018-11-26
      20.080000
      19.754073

      479
      2018-11-27
      21.049999
      19.775791

      480
      2018-11-28
      21.340000
      19.797510

      481
      2018-11-29
      21.430000
      19.819228

      482
      2018-11-30
      21.299999
      19.840947

      483
      2018-12-03
      23.709999
      19.862666

      484
      2018-12-04
      21.120001
      19.884384

      485
      2018-12-06
      21.299999
      19.906103

      486
      2018-12-07
      19.459999
      19.927821

      487
      2018-12-10
      19.990000
      19.949540

      488
      2018-12-11
      19.980000
      19.971259

      489
      2018-12-12
      20.480000
      19.992977

      490
      2018-12-13
      19.860001
      20.014696

      491
      2018-12-14
      19.900000
      20.036415

      492
      2018-12-17
      18.830000
      20.058133

      493
      2018-12-18
      19.500000
      20.079852

      494
      2018-12-19
      18.160000
      20.101570

      495
      2018-12-20
      17.940001
      20.123289

      496
      2018-12-21
      16.930000
      20.145008

      497
      2018-12-24
      16.650000
      20.166726

      498
      2018-12-26
      17.900000
      20.188445

      499
      2018-12-27
      17.490000
      20.210163

      500
      2018-12-28
      17.820000
      20.231882

      501
      2018-12-31
      18.459999
      20.253601

502 rows × 3 columns

```python
plt.figure(figsize=(16,8))
plt.plot(df.Date, df['Adj Close'])
plt.plot(df.Date, df['Forecast'])
plt.title('Line of Equation', equation_of_line)
plt.xlabel('Date', color='#1C2833')
plt.ylabel('Price', color='#1C2833')
plt.legend(loc='best')
plt.grid()
plt.show()
```


# Cerebellar Model Articulation Controller(CMAC)

## 概论
小脑模型的初始设想很简单，希望设计一个这样的模型：

1. **足够快**
2. **拟合**

### 足够快
对于第一点，传统的神经网络均是使用浮点数进行计算，使用浮点数显然存在两个缺点：其一是占用空间大，其二是运算不够快。但也存在非常明显的优点：计算精度高。

若为了在不太降低精度的条件下尽可能提高模型运算效率，显然有两个角度：其一是改进模型，其二是改变数值存储方式。

量化技术就是这样一类通过改变数值存储方式提高模型运算效率的方式。对于现代神经网络，训练通常采用32位浮点数，推理时则可以选用16位浮点数以提高精度，而当部署到边缘设备上时则可以进一步采用**int8量化技术**。

对于CMAC，同样的，为了提升运算效率，初始数据输入时会进行量化。此外，为了进一步提升效率，CMAC还引入了**哈希散列**，通过查表的方式将相近的输入映射到相似的地址上。

哈希散列同时也引入了不确定的因素。哈希散列是一种压缩映射，其很有可能将不同的输入映射到同一个地址，即导致了**碰撞**。从另一个角度讲，这也引入了非线性变换，即在原空间可能相隔非常远的两个输入，在映射后可能十分相近甚至发生**碰撞**。

### 拟合
为了实现拟合，CMAC在查表后建立了一个自适应线性层，实现地址到输出的线性估计
由于采用了哈希，实际上建立了输入与地址的映射表。在不考虑碰撞的情况下，一个特定的输入会激活特定的地址，而特定的地址会激活特定的自适应线性层的输入单元，这些单元则会连接到输出。

不同于传统的神经网络，进行推理时同层所有的神经元均会参与运算，CMAC中仅有被激活的输入单元才会参与运算，这显然也加速了CMAC的运算速度。

## 符号定义

### 空间
|符号|含义|
|:-:|:-:|
|$S$|输入空间|
|$M$|扩充地址空间|
|$MC$|扩充地址空间长度|
|$A_c$|虚拟存储空间|
|$A_p$|实际存储空间|
|$F$|输出空间|

### 数据
|符号|含义|
|:-:|:-:|
|$\bm{s}$|输入向量|
|$\bm{m}$|扩充后矩阵|
|$\bm{a}$|虚拟存储空间向量|
|$\bm{d}$|实际存储空间向量|
|$\hat{y}$|预测输出|
|$y$|真实输出|

### 参数
|符号|含义|
|:-:|:-:|
|s|输入空间维度|
|q|量化级|
|c|扩充地址维度|
|$N_p$|用于Hash运算的质数|
|$\bm{W}$|权矩阵|

## 正向运算

CMAC的整体流程如下：

* 输入空间$S$离散化
* 输入空间$S$ $\rightarrow$ 扩充地址空间$M$
* 扩充地址空间$M$ $\rightarrow$ 虚拟存储空间$A_c$
* 虚拟存储空间$A_c$ $\rightarrow$ 实际存储空间$A_p$
* 实际存储空间$A_p$ $\rightarrow$ 输出空间$F$

第零步为离散化。一方面是加速运算，另一方面也是配合后续的Hash

第一步是在进行升维

第二步是将第一步中升维到高维的多个分量组合为一个向量

第三步为Hash

第四步为自适应线性拟合

### 离散化

输入为$\bm{s}=[s_1, s_2, \cdots, s_s]$

设定第n个维度的取值范围为$[n_{min}, n_{max}]$，量化级为q_n

则第n个维度的离散值为
$$
\begin{equation}
    s_n = \lceil\frac{(s_n-n_{min})}{(n_{max}-n_{min})}*(q_n-1)\rceil + 1
\end{equation}
$$

### 输入空间到扩充地址空间

每一个输入分量均扩充到c维

对于一个特定的输入分量$s_n$，有对应的扩充后向量$\bm{m_n}$

扩充后向量按照如下的方式进行运算

定义如下的取余运算
$$
\begin{equation}
    \Psi(s_n) = mod(\frac{s_n-1}{c})+1
\end{equation}
$$
则$\bm{m_n}$的第$\Psi(s_n)$位为$s_n$，其他位依次推出

|$\bm{m_{n1}}$|$\bm{m_{n2}}$|$\cdots$|$\bm{m_{n\Psi(s_n)}}$|$\cdots$|$\bm{m_{nc}}$|
|:-:|:-:|:-:|:-:|:-:|:-:|
|$s_n+(c-\Psi(s_n)+1)$|$s_n+(c-\Psi(s_n)+2)$|$\cdots$|$s_n$|$\cdots$|$s_n+(c-\Psi(s_n))$|

### 扩充地址空间到虚拟存储空间

扩充地址空间为一个$s\times c$的矩阵，转换到虚拟存储空间后进行纵向连接，即进行如下操作

$$
\begin{equation}
    \bm{m} =
    \left[\begin{array}{cc}
        m_{11}&m_{12}&\cdots&m_{1c} \\
        \vdots&\ddots&\ddots&\vdots \\
        m_{s1}&m_{s2}&\cdots&m_{sc}
    \end{array}\right]
\end{equation}
$$

$$
\begin{equation}
    \begin{split}
        \bm{a}
        &= [a_1, a_2, \cdots, a_c]^T \\
        &= [m_{11}m_{21}\cdots m_{s1}, m_{12}m_{22}\cdots m_{s2}, \cdots, m_{1c}m_{2c}\cdots m_{sc}]^T
    \end{split}
\end{equation}
$$

### 虚拟存储空间到实际存储空间

这一步即为Hash，在这里采用取余运算的方式，类似于式2有：

$$
\begin{equation}
    \Psi(a_n) = mod(\frac{a_n-1}{N_p})+1
\end{equation}
$$

$$
\begin{equation}
    \begin{split}
        \bm{d}
        &= [d_1, d_2, \cdots, d_c]^T \\
        &= [\Psi(a_1), \Psi(a_2), \cdots, \Psi(a_c)]^T
    \end{split}
\end{equation}
$$

### 实际存储空间到输出空间

这一步采用简单的线性变换

上述得到的是地址，在CMAC中，为了加速运算，最终一步是通过查询实现的，

权矩阵$\bm{W}\in\mathcal{R}^{c \times N_p}$

其中$c$为地址的维度，$N_p$为取余运算的除数，对于以$N_p$为底的除法，显然得到的余数不可能大于$N_p$

输出即为对应地址位置的权值之和

$$
\begin{equation}
    \hat{y} = \sum_{i=0}^{c}W[i, \Psi(a_i)]
\end{equation}
$$

上述方法均是在从1开始计数的背景下讨论的，在具体实现中将从0开始计数

## 参数学习

定义损失函数

$$
\begin{equation}
    \mathcal{L} = ||\hat{y}-y||_2^2
\end{equation}
$$

对权值求偏导

$$
\begin{equation}
    \begin{split}
    \frac{\partial \mathcal{L}}{\partial \bm{W}}
    &= \frac{||\hat{y}-y||_2^2}{\partial \bm{W}} \\
    &= \frac{(\sum_{i=0}^{c}W[i, \Psi(a_i)]-y)^2}{\partial \bm{W}} \\
    &= 2(\sum_{i=0}^{c}W[i, \Psi(a_i)]-y)\frac{\sum_{i=0}^{c}W[i, \Psi(a_i)]}{\partial \bm{W}}
    \end{split}
\end{equation}
$$

$$
\begin{equation}
    \frac{\partial \mathcal{L}}{W_{ij}} =
    \left\{
    \begin{array}{cc}
    0,&d_i \neq j+1 \\
    2(\sum_{i=0}^{c}W[i, \Psi(a_i)]-y),&else
    \end{array}
    \right.
\end{equation}
$$

获得参数更新函数

$$
\begin{equation}
    \bm{W}(t+1) = \bm{W}(t) - \eta\frac{\partial \mathcal{L}}{\bm{W}(t)}
\end{equation}
$$

```python
import os
import random
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
import seaborn as sn
import imageio

%matplotlib inline
```

```python
class CMAC(object):

    def __init__(self,
                 input_dim,
                 input_range,
                 q_level,
                 expend_dim,
                 hash_number):
        """
        input_dim: 输入维度
        input_range: 输入取值范围，默认需要一个list
        q_level: 量化级，默认需要输入一个list
        expend_dim: 扩充地址维度
        hash_number: 用于散列的质数
        """

        self.input_dim = input_dim
        self.input_range = np.array(input_range)
        self.q_level = q_level
        self.expend_dim = expend_dim
        self.hash_number = hash_number

        # 输出权值矩阵
        random.seed(1024)
        np.random.seed(1024)
        self.weight_matrix = np.zeros((self.expend_dim, self.hash_number))

        # 数据存储空间向量
        self.real_vector = None
        self.output_vector = None

    def forward(self, x):
        """
        x: 输入向量
        """

        # ------------- 离散化 ---------------
        input_q = self._quantification(np.array(x))

        # ------------- 输入空间到扩充地址空间 ------------------
        # (self.expend_dim, self.input_dim)
        expend_matrix = self._input2expend(input_q)

        # ------------- 扩充地址空间到虚拟存储空间 -----------------
        # (self.expend_dim, 1)
        virtual_vector = self._expend2virtual(expend_matrix)

        # ------------- 虚拟存储空间到实际存储空间 ------------------
        # (self.expend_dim, 1)
        self.real_vector = self._virtual2real(virtual_vector)

        # ------------- 实际存储空间到输出空间 --------------------
        # (self.output_dim, 1)
        self.output_value = self._real2output(self.real_vector)

        return self.output_value

    def optim(self, true_output, lr):
        """
        true_output: 真实输出
        """

        # 更新mask
        partial_matrix = np.zeros((self.expend_dim, self.hash_number))
        partial_matrix[range(0, self.expend_dim), self.real_vector.reshape(-1)] = 1
        self.weight_matrix -= lr * (self.output_value - true_output) * partial_matrix

    def _quantification(self, input_vector):
        """
        input_vector: 输入向量
        """
        input_q = np.zeros(self.input_dim, dtype=np.int32)
        # (self.input_dim)
        for i in range(self.input_dim):
            _input_range = self.input_range[i, :]
            input_q[i] = np.math.ceil((input_vector[i]-_input_range[0])*(self.q_level[i]-1)/(_input_range[1]-_input_range[0]))

        return input_q

    def _input2expend(self, input_q):
        """
        input_q: 量化后的输入向量
        """
        expend_matrix = np.zeros((self.input_dim, self.expend_dim))

        for i in range(self.input_dim):

            # 计算取余运算
            phi_ = input_q[i] % self.expend_dim

            if phi_ != 0:
                # index < phi_
                add_number_list_1 = np.array(range(0, phi_))
                # index > phi_
                add_number_list_2 = np.array(range(0, self.expend_dim-phi_))

                expend_matrix[i, :phi_] = input_q[i] + self.expend_dim - phi_ + add_number_list_1
                expend_matrix[i, phi_:] = input_q[i] + add_number_list_2
            else:
                expend_matrix[i] = input_q[i] + np.array(range(0, self.expend_dim))

        return expend_matrix.astype(np.int32).T

    def _expend2virtual(self, expend_matrix):
        """
        expend_matrix: 扩充地址空间矩阵
        """
        virtual_vector = np.zeros((self.expend_dim, 1), dtype=np.int32)

        # 进行组合
        mul_num = 1
        for i in range(self.input_dim):
            virtual_vector += expend_matrix[:, i:i+1] * mul_num
            mul_num *= self.q_level[i] + self.expend_dim - 1

        return virtual_vector

    def _virtual2real(self, virtual_vector):
        """
        virtual_vector: 虚拟存储空间向量
        """
        real_vector = np.zeros((self.expend_dim, 1), dtype=np.int32)
        for i in range(self.expend_dim):
            real_vector[i] = virtual_vector[i]%self.hash_number

        return real_vector

    def _real2output(self, real_vector):
        """
        real_vector: 实际存储空间向量
        """
        output_value = np.sum(self.weight_matrix[range(0, self.expend_dim), real_vector.reshape(-1)])

        return output_value
```

```python
# 测试数据

# 输入维度
input_dim = 2
# 输入范围
input_range = [[0, 6.2], [0, 6.2]]
# 量化级
q_levle = [62, 62]
# 扩充地址空间维度
expend_dim = 7
# 散列质数
hash_number = 5001
# 学习率
lr = 0.1
# 输出维度
output_dim = 1

# 测试输入
input_vector = [0.2, 0.2]
# 测试输出
output_ = 1

my_cmac = CMAC(input_dim=input_dim,
               input_range=input_range,
               q_level=q_levle,
               expend_dim=expend_dim,
               hash_number=hash_number)

# 离散值输出
input_q = my_cmac._quantification(input_vector)
print("离散\n", input_q)
# 输入空间到扩充地址空间
expend_matrix = my_cmac._input2expend(input_q)
print("扩充地址空间\n", expend_matrix)
# 扩充地址空间到虚拟存储空间
virtual_vector = my_cmac._expend2virtual(expend_matrix)
print("虚拟存储空间\n", virtual_vector)
# 虚拟存储空间到实际存储空间
real_vector = my_cmac._virtual2real(virtual_vector)
print("实际存储空间\n", real_vector)
# 实际存储空间到输出空间
output_value = my_cmac._real2output(real_vector)
print("输出\t", output_value)

# 参数优化
print("参数学习")
for step in range(10):
    output_value_2 = my_cmac.forward(input_vector)
    my_cmac.optim(output_, lr)
    print("step:{}\t output_value:{:.6f}".format(step, output_value_2))
```

    离散
     [2 2]
    扩充地址空间
     [[7 7]
     [8 8]
     [2 2]
     [3 3]
     [4 4]
     [5 5]
     [6 6]]
    虚拟存储空间
     [[483]
     [552]
     [138]
     [207]
     [276]
     [345]
     [414]]
    实际存储空间
     [[483]
     [552]
     [138]
     [207]
     [276]
     [345]
     [414]]
    输出	 0.0
    参数学习
    step:0	 output_value:0.000000
    step:1	 output_value:0.700000
    step:2	 output_value:0.910000
    step:3	 output_value:0.973000
    step:4	 output_value:0.991900
    step:5	 output_value:0.997570
    step:6	 output_value:0.999271
    step:7	 output_value:0.999781
    step:8	 output_value:0.999934
    step:9	 output_value:0.999980

```python
# 对函数进行拟合

# 拟合函数f(x1, x2) = sin(x1)cos(x2)
# x1范围[-3, 3]，总点数100
# x2范围[-3, 3]，总点数100

# ------------------- 超参数 -------------------
# 输入维度
input_dim = 2
# 输入范围
input_range = [[-3, 3], [-3, 3]]
# 量化级
q_levle = [100, 100]
# 扩充地址空间维度
expend_dim = 13
# 散列质数
hash_number = 101
# 学习率
lr = 0.005
# 最大epoch
iteration = 40000

# ------------------- 模型 -----------------------
my_cmac = CMAC(input_dim=input_dim,
               input_range=input_range,
               q_level=q_levle,
               expend_dim=expend_dim,
               hash_number=hash_number)

# ------------------- 数据 -----------------------
# 生成数据的分辨率
sample_resolution = 100
x1, x2 = np.meshgrid(np.linspace(-3, 3, sample_resolution), np.linspace(-3, 3, sample_resolution))

train_x_list = np.concatenate((x1.reshape(-1, 1), x2.reshape(-1, 1)), axis=1)
train_y_list = np.sin(train_x_list[:, 0:1]) * np.cos(train_x_list[:, 1:])

# ------------------- 参数优化 ------------------------
print("参数学习")
random.seed(1024)
print_frequency = 1
train_loss = 0
train_loss_dict = dict()
train_pred_recoder = list()
params_recoder = list()

# 对所有输入进行预测
pred_matrix = np.zeros((sample_resolution, sample_resolution))
for _x1 in range(sample_resolution):
    for _x2 in range(sample_resolution):
        pred_y = my_cmac.forward([x1[_x1, _x2], x2[_x1, _x2]])

        pred_matrix[_x1, _x2] = pred_y
        train_loss += (pred_y - np.sin(x1[_x1, _x2]) * np.cos(x2[_x1, _x2]))**2

train_loss /= sample_resolution ** 2
train_loss_dict[0] = train_loss
print("iterations:[{}/{}] avg loss:{:.6f}".format(0, iteration, train_loss))
train_loss = 0
train_pred_recoder.append(pred_matrix)
params_recoder.append(my_cmac.weight_matrix.copy())

# 开始训练
for i in range(1, iteration+1):

    sample_index = random.randint(0, len(train_x_list)-1)

    sample_x = train_x_list[sample_index]
    sample_y = train_y_list[sample_index]

    pred_y = my_cmac.forward(sample_x)
    my_cmac.optim(sample_y, lr)

    if i % print_frequency == 0 or i % iteration == 0:
        # 对所有输入进行预测
        pred_matrix = np.zeros((sample_resolution, sample_resolution))
        for _x1 in range(sample_resolution):
            for _x2 in range(sample_resolution):

                pred_y = my_cmac.forward([x1[_x1, _x2], x2[_x1, _x2]])

                pred_matrix[_x1, _x2] = pred_y
                train_loss += (pred_y - np.sin(x1[_x1, _x2]) * np.cos(x2[_x1, _x2]))**2

        train_loss /= sample_resolution * sample_resolution
        train_loss_dict[i] = train_loss
        print("iterations:[{}/{}] avg loss:{:.6f}".format(i, iteration, train_loss))
        train_loss = 0
        train_pred_recoder.append(pred_matrix)
        params_recoder.append(my_cmac.weight_matrix.copy())

        print_frequency = int(pow(1.1, len(train_loss_dict)))
```

    参数学习
    iterations:[0/40000] avg loss:0.249668
    iterations:[1/40000] avg loss:0.248866
    iterations:[2/40000] avg loss:0.248780
    iterations:[3/40000] avg loss:0.247917
    iterations:[4/40000] avg loss:0.247636
    iterations:[5/40000] avg loss:0.247176
    iterations:[6/40000] avg loss:0.247146
    iterations:[7/40000] avg loss:0.247127
    iterations:[8/40000] avg loss:0.247081
    iterations:[10/40000] avg loss:0.246616
    iterations:[12/40000] avg loss:0.245713
    iterations:[14/40000] avg loss:0.244969
    iterations:[15/40000] avg loss:0.244593
    iterations:[18/40000] avg loss:0.244322
    iterations:[21/40000] avg loss:0.244281
    iterations:[24/40000] avg loss:0.243114
    iterations:[28/40000] avg loss:0.241051
    iterations:[30/40000] avg loss:0.238231
    iterations:[35/40000] avg loss:0.235232
    iterations:[36/40000] avg loss:0.235204
    iterations:[42/40000] avg loss:0.232649
    iterations:[49/40000] avg loss:0.231421
    iterations:[56/40000] avg loss:0.229389
    iterations:[64/40000] avg loss:0.226473
    iterations:[72/40000] avg loss:0.222563
    iterations:[80/40000] avg loss:0.219286
    iterations:[88/40000] avg loss:0.217603
    iterations:[91/40000] avg loss:0.215672
    iterations:[98/40000] avg loss:0.213108
    iterations:[105/40000] avg loss:0.209429
    iterations:[119/40000] avg loss:0.203817
    iterations:[133/40000] avg loss:0.198528
    iterations:[147/40000] avg loss:0.193617
    iterations:[161/40000] avg loss:0.187870
    iterations:[175/40000] avg loss:0.183861
    iterations:[196/40000] avg loss:0.176829
    iterations:[210/40000] avg loss:0.171412
    iterations:[238/40000] avg loss:0.163909
    iterations:[259/40000] avg loss:0.157559
    iterations:[287/40000] avg loss:0.151061
    iterations:[315/40000] avg loss:0.141405
    iterations:[343/40000] avg loss:0.134490
    iterations:[378/40000] avg loss:0.126971
    iterations:[420/40000] avg loss:0.119266
    iterations:[462/40000] avg loss:0.111286
    iterations:[504/40000] avg loss:0.104249
    iterations:[560/40000] avg loss:0.094525
    iterations:[616/40000] avg loss:0.085898
    iterations:[679/40000] avg loss:0.077194
    iterations:[742/40000] avg loss:0.069259
    iterations:[819/40000] avg loss:0.062141
    iterations:[903/40000] avg loss:0.054239
    iterations:[994/40000] avg loss:0.047911
    iterations:[1092/40000] avg loss:0.041417
    iterations:[1197/40000] avg loss:0.035435
    iterations:[1323/40000] avg loss:0.029391
    iterations:[1449/40000] avg loss:0.025351
    iterations:[1596/40000] avg loss:0.019751
    iterations:[1757/40000] avg loss:0.016564
    iterations:[1932/40000] avg loss:0.013696
    iterations:[2128/40000] avg loss:0.011093
    iterations:[2338/40000] avg loss:0.008763
    iterations:[2576/40000] avg loss:0.006438
    iterations:[2835/40000] avg loss:0.005285
    iterations:[3115/40000] avg loss:0.004406
    iterations:[3430/40000] avg loss:0.003611
    iterations:[3773/40000] avg loss:0.003010
    iterations:[4151/40000] avg loss:0.002522
    iterations:[4564/40000] avg loss:0.002071
    iterations:[5019/40000] avg loss:0.001858
    iterations:[5523/40000] avg loss:0.001614
    iterations:[6076/40000] avg loss:0.001406
    iterations:[6685/40000] avg loss:0.001228
    iterations:[7357/40000] avg loss:0.001124
    iterations:[8092/40000] avg loss:0.001018
    iterations:[8897/40000] avg loss:0.000920
    iterations:[9793/40000] avg loss:0.000854
    iterations:[10766/40000] avg loss:0.000783
    iterations:[11844/40000] avg loss:0.000728
    iterations:[13034/40000] avg loss:0.000680
    iterations:[14336/40000] avg loss:0.000637
    iterations:[15771/40000] avg loss:0.000600
    iterations:[17346/40000] avg loss:0.000563
    iterations:[19082/40000] avg loss:0.000526
    iterations:[20993/40000] avg loss:0.000504
    iterations:[23086/40000] avg loss:0.000477
    iterations:[25396/40000] avg loss:0.000455
    iterations:[27937/40000] avg loss:0.000442
    iterations:[30730/40000] avg loss:0.000421
    iterations:[33810/40000] avg loss:0.000406
    iterations:[37191/40000] avg loss:0.000392
    iterations:[40000/40000] avg loss:0.000380

```python
# ---------------------------- 绘图 ------------------------
# 探测碰撞
real_address_heatmap = np.zeros((expend_dim, hash_number))
for train_sample in train_x_list:
    pred_y = my_cmac.forward(train_sample)
    real_address_heatmap[range(0, my_cmac.expend_dim), my_cmac.real_vector.reshape(-1)-1] += 1

plt.figure(figsize=(30, 10))
plt.title("Collisions")
sn.heatmap(real_address_heatmap)
plt.show()

# 绘制训练过程图
fig = plt.figure(figsize=(20, 20))
for i in range(len(train_loss_dict)):
    plt.cla()
    plt.clf()
    ax1 = fig.add_subplot(2, 2, 1, projection='3d')
    ax1.set_title("Ground True", fontsize=20)
    plt.xticks(fontsize=20)
    plt.yticks(fontsize=20)
    ax1.tick_params(axis='z', labelsize=20)
    ax1.set_zlim(-1, 1)
    ax1.plot_surface(x1, x2, np.sin(x1) * np.cos(x2), cmap="rainbow")

    ax2 = fig.add_subplot(2, 2, 2, projection='3d')
    ax2.set_title("Pred", fontsize=20)
    plt.xticks(fontsize=20)
    plt.yticks(fontsize=20)
    ax2.tick_params(axis='z', labelsize=20)
    ax2.set_zlim(-1, 1)
    ax2.plot_surface(x1, x2, train_pred_recoder[i].reshape((sample_resolution, sample_resolution)), cmap="rainbow")

    ax3 = fig.add_subplot(2, 2, 3)
    ax3.set_title("loss & iteration:{}".format(list(train_loss_dict.keys())[i]), fontsize=20)
    ax3.set_xlabel("iterations", fontsize=20)
    ax3.set_ylabel("loss", fontsize=20)
    plt.xticks(fontsize=20)
    plt.yticks(fontsize=20)
    ax3.plot(list(train_loss_dict.keys())[:i], list(train_loss_dict.values())[:i])
    ax3.set_aspect(1.0/ax3.get_data_ratio(), adjustable="box")

    ax4 = fig.add_subplot(2, 2, 4)
    ax4.set_title("weight params & iteration:{}".format(list(train_loss_dict.keys())[i]), fontsize=20)
    plt.xticks(fontsize=20)
    plt.yticks(fontsize=20)
    sn.heatmap(params_recoder[i], vmax=0.1, vmin=-0.1, cmap="YlGnBu")

    plt.savefig("./images/temp/{}.png".format(i), dpi=70)
plt.show()

with imageio.get_writer("./images/{}.gif".format("CMAC_sin_cos"), mode="I", fps=10) as Writer:
    for ind in range(len(train_loss_dict)):
        image = imageio.imread("./images/temp/{}.png".format(ind))
        os.remove("./images/temp/{}.png".format(ind))
        Writer.append_data(image)
```