PySciBlog

Python is under investigation of future

PCA. Собственные векторы и атрактор Лоренца

Вступление

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d

np.random.seed(1)

steps = 3000
tr=25

scatter_matrix = np.zeros((3,3))
U=np.zeros((steps,tr,3))

def lorenz(x, y, z, s=10, r=28, b=8./3, dt=0.01) :
    return [x + (s*(y - x))*dt, y + (r*x - y - x*z)*dt, z + (x*y - b*z)*dt]


U[0]=-15+30*np.random.random((tr,3))

for i in range(0,steps-1):
    for j in range(0,tr):
        U[i+1][j][0], U[i+1][j][1], U[i+1][j][2]=lorenz(U[i][j][0], U[i][j][1], U[i][j][2]) 

class DrawVectors(FancyArrowPatch):
    def __init__(self, xs, ys, zs, *args, **kwargs):
        FancyArrowPatch.__init__(self, (0,0), (0,0), *args, **kwargs)
        self._verts3d = xs, ys, zs

    def draw(self, renderer):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
        self.set_positions((xs[0],ys[0]),(xs[1],ys[1]))
        FancyArrowPatch.draw(self, renderer)

def CalculateVectors(U):
    global scatter_matrix
    mean_vector = np.array([[np.mean(U[:,0])],[np.mean(U[:,1])],[np.mean(U[:,2])]])
    for i in range(tr):
        scatter_matrix += (U[i,:].reshape(3,1) - mean_vector).dot((U[i,:].reshape(3,1) - mean_vector).T)

    eig_val_sc, eig_vec_sc = np.linalg.eig(scatter_matrix)
    for v in eig_vec_sc.T:
        a = DrawVectors([0,10*v[0]+mean_vector[0]], 
                        [0,10*v[1]+mean_vector[1]], 
                        [0,10*v[2]+mean_vector[2]], mutation_scale=20, lw=1, arrowstyle="-|>", color="c")

        ax.add_artist(a)

fig = plt.figure()
ax=fig.gca(projection='3d')

k=0
def animat(t):
    global k
    ax.cla()
    CalculateVectors(U[k])
    ax.scatter(U[k,:,0], U[k,:,1], U[k,:,2],c='r')

    ax.set_zlim(0,60)
    ax.set_ylim(-25,25)
    ax.set_xlim(-19,19)

    k+=1

anim = animation.FuncAnimation(fig, animat, frames=steps-2,interval=5)
anim.save('lorenz.mp4', dpi=100, bitrate=163840, fps=30)
#plt.show(anim)
print('OK')