import numpy as np
import matplotlib.pyplot as plt
from sympy import*
# Données pour 20 individus sur 3 variables poids taille âge
data = [[72, 175, 28],[65, 162, 32],[80, 185, 45],[58, 155, 29],[75, 178, 38],[63, 168, 41],[85, 192, 52],[70, 172, 35],[62, 160, 31],[78, 180, 48],
    [68, 170, 33],[74, 176, 42],[61, 158, 27],[77, 182, 46],[66, 165, 34],[71, 174, 39],[64, 163, 30],[79, 184, 49],[69, 171, 36],[76, 179, 44]]    
# Conversion en matrice SymPy
X = Matrix(data)
# Calcul des moyennes
n_individus = X.rows
moyennes = []
for i in range(3):
    somme = sum(X[:, i])
    moyenne = somme / n_individus
    moyennes.append(moyenne)
# Calcul des écarts-types et variances
ecarts_types = []
variances = []
for i in range(3):
    # Calcul de la variance
    somme_carres = sum((x - moyennes[i])**2 for x in X[:, i])
    variance = somme_carres / n_individus
    variances.append(variance)
    # Calcul de l'écart-type
    ecart_type = sqrt(variance)
    ecarts_types.append(ecart_type)
# Construction de la matrice de covariance
cov_matrix = Matrix.zeros(3, 3)
for i in range(3):
    for j in range(3):
        somme = sum((X[k, i] - moyennes[i]) * (X[k, j] - moyennes[j]) for k in range(n_individus))
        cov_ij = somme / n_individus
        cov_matrix[i, j] = cov_ij
# Construction de la matrice de corrélation
corr_matrix = Matrix.zeros(3, 3)
for i in range(3):
    for j in range(3):
        if ecarts_types[i] != 0 and ecarts_types[j] != 0:
            corr_ij = cov_matrix[i, j] / (ecarts_types[i] * ecarts_types[j])
            corr_matrix[i, j] = corr_ij
        else:
            corr_matrix[i, j] = 0
# on convertit les coefficients de la matrice corr_matrix en flottants
B=corr_matrix
for i in range(3):
    for j in range(3):
        B[i,j]=float(B[i,j])
A=B
# 2.  Calcul des valeurs propres et vecteurs propres
eigs = A.eigenvects()  # [(val_propre, multiplicité, [vecteurs_propres])]
# 3.  Trier les valeurs propres dans l'ordre décroissant
eigs_sorted = sorted(eigs, key=lambda x: x[0], reverse=True)
# 4. déterminer la matrice diagonale D formée des valeurs propres 
# et P la matrice  de passage qui est orthogonale
D = Matrix.diag(*[ev[0] for ev in eigs_sorted])
P = Matrix.hstack(*[ev[2][0].normalized() for ev in eigs_sorted])
VectPropres=P.columnspace()
# Créer les coordonnées des vecteurs propres
x,y,z=VectPropres[0][0],VectPropres[0][1],VectPropres[0][2]
xx,yy,zz=VectPropres[1][0],VectPropres[1][1],VectPropres[1][2]
xxx,yyy,zzz=VectPropres[2][0],VectPropres[2][1],VectPropres[2][2]
# Créer un objet Axes3D pour le graphique 3D
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Tracé des 3 vecteurs propres (fois 3 pour mieux visualiser) 
ax.quiver(0,0,0,
          3*x,3*y,3*z,
          color='red', arrow_length_ratio=0.1)
ax.quiver(0,0,0,
          3*xx,3*yy,3*zz,
          color='red', arrow_length_ratio=0.1)
ax.quiver(0,0,0,
          3*xxx,3*yyy,3*zzz,
          color='red', arrow_length_ratio=0.1)
# Mise en forme du graphe
ax.set_xlim([-5,5])
ax.set_ylim([-5,5])
ax.set_zlim([-5,5])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Base des Vecteurs propres(X3) en 3D')
plt.savefig("/home/jm/Bureau/fig.png")
plt.show()
